home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / assembler / progasm2.lha / LEZIONI / LEZIONE9.TXT / LEZIONE9.TXT
Text File  |  1995-10-23  |  100KB  |  2,190 lines

  1.  
  2.                                   '''
  3.                                  (o o)
  4. +---------------------------oOOO--(_)-------------------------------------+
  5. |                                      |
  6. |          CORSO DI ASSEMBLER - LEZIONE 9              |
  7. |                                      |
  8. +--------------------------------------oOOO-------------------------------+
  9.                                 |__|__|
  10.                                  || ||
  11.                                 ooO Ooo
  12.  
  13. Autori: Luca Forlizzi, Alvise Spano', Fabio Ciucci
  14.  
  15. (Directory Sorgenti5) - quindi scrivere "V Assembler2:sorgenti5"
  16.  
  17.      ·×X×··×X×··×X×··×X×··×X×··×X×··×X×··×X×··×X×··×X×··×X×··×X×·
  18.                 IL BLITTER
  19.      ·×X×··×X×··×X×··×X×··×X×··×X×··×X×··×X×··×X×··×X×··×X×··×X×·
  20.  
  21. In questa lezione inizieremo a parlare del blitter. Chiunque possieda
  22. un Amiga avra` sicuramente sentito parlare di questo speciale circuito
  23. posto all'interno del suo computer che risulta esserne uno dei maggiori
  24. punti di forza qualora lo si confronti con altri computer. Non tutti
  25. pero` sanno che cosa il blitter sia in realta` e per quali motivi sia
  26. cosi` tanto utile. In effetti la maggioranza degli effetti speciali che
  27. potete ammirare nelle demo (come per esempio gli scrolltext sinusoidali
  28. o i vectorballs) fanno uso del blitter. E allora, vi chiederete, come
  29. mai si possono realizzare questi effetti anche sui dei PC che non hanno
  30. il blitter? Il motivo e` che in realta` tutto cio` che il blitter puo`
  31. fare, potrebbe essere fatto con il microprocessore, ed e` appunto in
  32. questo modo che fanno i PC. Il blitter, pero` e` in grado di svolgere i
  33. suoi compiti in maniera molto piu` veloce, in certi casi anche 10 volte
  34. piu` veloce. E` grazie al blitter che effetti speciali che con un PC si
  35. possono realizzare solo se si ha a disposizione un 386 veloce o
  36. addirittura un 486, mentre sono ordinaria amministrazione per un Amiga 500
  37. il cui processore (68000 a 7Mhz come sapete bene) e` molto piu` lento dei
  38. 386 e 486. Quindi capirete che per chi voglia programmare demo o giochi
  39. sull'Amiga, la conoscenza del blitter sia indispensabile. Cominceremo
  40. lo studio delle capacita` del blitter partendo dalle piu` semplici, che
  41. a prima vista potrebbero sembrare misere, ma che scopriremo via via
  42. nascondere la potenza che ha permesso la creazione dei giochi e delle
  43. demo piu` spettacolari. Occorre pero' notare che i programmi scritti per
  44. 68020+ spesso tendono ad usare la CPU anziche' il blitter, dato che
  45. quest'ultimo non aumenta di velocita'.
  46.  
  47.       .    .
  48.   ,      ,   ,  ..            ______________
  49.     .     ..     · ..        /      ,      ¬\           ____
  50.       .    ·:: ..   ·:. .:,_/  ¯¯¯¯¯  -----' \         `----'
  51.                 ·::: ..: ::`________  ________\ ____________________
  52.     .·  :·  · :::. . .  ·:  )(  ¬(X ) ) ×)¯ )  \                  _/
  53.            ,   :::·.  ..:. ,  ¯¯¯¯¯¯ (¯¯¯¯¯¯   /_____________ ___ T
  54.        ·:    .       . · '¯\_   _    ¯\  _   _/   `-----||( ¡¡:::!|
  55.   .       :·      .        /    /   (,_) \    \ xCz     ll  !|:::||
  56.      .,             _______\   / ________ \   /_______   ¯¯T |:::||
  57.                   /ØØØØØØØØØ\   /_T_T_T_T\   /ØØØØØØØØØ\   | !¦¦¦!|
  58.                  /ØØØØØØØØØØØ\__¯ ¯ ¯ ¯ ¯¯__/ØØØØØØØØØØØ\  l______!
  59.                 /ØØØØØØØØØØØØØØ`----------'ØØØØØØØØØØØØØØ\  `----'
  60.                ·ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ·
  61.  
  62.  
  63. *******************************************************************************
  64. *            FUNZIONI DEL BLITTER                      *
  65. *******************************************************************************
  66.  
  67. La parola "blitter" e` un'abbreviazione di "BLock Image TransferER"
  68. ovvero "copiatore di blocchi di immagine". Il blitter e` dunque uno
  69. strumento che ci permette di spostare "pezzi" di immagini. In realta`,
  70. come scoprirete in seguito, questa e` solo una delle capacita` del
  71. blitter, che e` in grado di effettuare anche operazioni piu` complesse.
  72. Come sapete, un immagine all'interno dell'Amiga e` costituita
  73. semplicemente da una zona di memoria che contiene i dati che definiscono
  74. il colore di ogni singolo pixel. Se non vi ricordate bene come sono
  75. formate le immagini e` bene che andiate a ripassare le lezioni 4 e 5 prima di
  76. proseguire oltre. Quando il blitter effettua un operazione su un "pezzo"
  77. di immagine, lavora in realta` sulla zona di memoria che forma il "pezzo"
  78. di immagine in questione. In effetti il blitter opera semplicemente su
  79. zone di memoria, indipendentemente dal fatto che esse contengano un'immagine
  80. grafica, un suono o il codice di un programma.
  81. Questo significa che il blitter puo` essere utilizzato anche in compiti che
  82. non riguardano la grafica.
  83. E` importante precisare, pero` che il blitter, al pari del copper dei
  84. circuiti audio e di tutto il resto dei chip "custom" dell'Amiga, non
  85. e` in grado di operare su tutta la memoria disponibile, ma solo su una
  86. parte di essa denominata "chip ram".
  87.  
  88. Per accedere alla memoria il blitter utilizza i canali DMA di cui si e` parlato
  89. in termini generici nella lezione 8, a cui vi rimando in caso di dubbi.
  90. Il blitter ha a disposizione ben 4 canali DMA, di cui 3 (denominati A,B e C)
  91. servono per LEGGERE dati dalla RAM (e per questo vengono detti canali
  92. "sorgente") mentre il quarto (canale D) serve per SCRIVERE nella memoria
  93. (e pertanto e` detto canale "destinazione"). Come tutti i canali DMA, quelli
  94. del blitter trasferiscono una word di dati alla volta. 
  95.  
  96. Lo schema generale di un'operazione blitter (detta "BLITTATA") e` molto
  97. semplice: il blitter, attraverso i canali A,B e C, legge dati dalla memoria,
  98. effettua delle operazioni su di essi e scrive i risutati in memoria attraverso
  99. il canale D. Per eseguire una blittata e` dunque necessario specificare le 
  100. seguenti informazioni:
  101.  
  102. 1) quali canali usare per questa operazione
  103. 2) che operazione effettuare sui dati letti
  104. 3) per ogni canale usato, l'indirizzo da dove iniziare a leggere e scrivere
  105. 4) quanti dati leggere o scrivere
  106.  
  107. Notate che la quantita` di dati letta (o scritta) durante un'operazione e` la
  108. stessa per tutti e quattro i canali: se in un'operazione uso i canali A,B e D,
  109. il numero di words che vengono lette attraverso il canale A e` uguale al numero
  110. di words che vengono lette attraverso il canale B e al numero di words che
  111. che vengono scritte attraverso il canale D.
  112.  
  113. Queste informazioni vengono specificate attraverso alcuni registri hardware.
  114. I registri che controllano il blitter sono, come tutti i registri hardware,
  115. a 16 bit. Vi sono pero` molti registri che hanno indirizzi consecutivi.
  116. Questo fatto rende possibile accedervi a coppie utilizzando delle "move.l"
  117. invece che delle "move.w", analogamente a quanto abbiamo visto per le coppie
  118. di registri BPLxPT ($dff0e0...) e COPxLC ($dff080...).
  119.  
  120. Prima di iniziare a scrivere nei registri, e` necessario pero` essere certi che
  121. il blitter sia fermo, cioe` che non stia gia` compiendo un'altra operazione.
  122. E' indispensabile aspettare che l'ultima "blittata" sia finita prima di farne
  123. un'altra, altrimenti si potrebbero causare esplosioni e crolli nel raggio di
  124. 100 metri, un vero cataclisma, paragonabile ad un bombardamento aereo.
  125.  
  126. Per sapere se il blitter e` fermo o sta "blittando", basta controllare
  127. lo stato di un bit (il bit 6) del registro DMACONR ($dff002).
  128. Se tale bit vale 1 allora il blitter sta lavorando, mentre se vale 0 vuol
  129. dire che il blitter ha finito.
  130. In pratica, quindi basta una semplice istruzione assembler:
  131.  
  132.  
  133. AspettaBlit:
  134.     btst    #6,$dff002    ; dmaconr - il blitter ha finito?
  135.     bne.s    AspettaBlit    ; Non andare avanti fino a che non ha finito
  136.  
  137.  
  138. Purtroppo, a complicare le cose c'e` un fastidiosissimo BUG hardware nelle
  139. prime versioni del chip Agnus (il chip che contiene il blitter) a causa del
  140. quale la prima volta che viene effettuata una lettura del bit in questione si
  141. ha un risultato sbagliato: bisogna effettuare una lettura a vuoto prima di
  142. poter conoscere con esattezza lo stato del bit. 
  143.  
  144. Dopo esserci assicurati che il blitter sia fermo, possiamo scrivere
  145. nei registri le informazioni che gli sono necessarie per la blittata e
  146. che abbiamo elencato sopra.
  147.  
  148. Vediamo ora in dettaglio come si procede.
  149.  
  150. 1) Per ogni blittata possiamo abilitare o disabilitare indipendentemente i
  151.   canali DMA, in modo da usare solo quelli che ci interessano, mediante
  152.   dei bit di abilitazione che, se vengono settati a 1, abilitano il canale;
  153.   se invece vengono azzerati lo disabilitano. I bit di abilitazione si trovano
  154.   nel registro di controllo BLTCON0 ($dff040):
  155.  
  156. canale        nome bit di abilitazione    posizione del bit in BLTCON0
  157.  
  158.   A            SRCA                8
  159.   B            SRCB                9
  160.   C            SRCC                10
  161.   D            DEST                11
  162.  
  163. 2) Per specificare quale operazione effettuare si usano i bit da 0 a 7 del
  164.   registro di controllo BLTCON0, detti MINTERMS. Il valore che assumono tali
  165.   bit determina l'operazione effettuata dal blitter. Il funzionamento dei 
  166.   MINTERMS e` abbastanza complicato, e lo spiegheremo in dettaglio in seguito.
  167.  
  168. 3) Vediamo ora come indicare gli indirizzi di partenza dei canali.
  169.   Ad ogni canale e` connesso un puntatore alla chip RAM che serve appunto per
  170.   memorizzare l'indirizzo di partenza di un'operazione. Durante l'operazione
  171.   il valore contenuto nel puntatore variera` automaticamente, indicando
  172.   di volta in volta l'indirizzo della word che il blitter legge o scrive.
  173.   Un puntatore e` costituito (come per i canali DMA degli sprites e dei planes)
  174.   da una coppia di registri a 16 bit, uno che contiene i 16 bit meno
  175.   significativi (cioe` piu` bassi) e uno che contiene i rimanenti (alti).
  176.   In questa tabella sono riassunti i nomi e gli indirizzi dei puntatori:
  177.  
  178. canale        registro alto            registro basso
  179.  
  180.         nome       indirizzo        nome       indirizzo
  181.  
  182.   A        BLTAPTH       $DFF050        BLTAPTL       $DFF052
  183.   B        BLTBPTH       $DFF04C        BLTBPTL       $DFF04E
  184.   C        BLTCPTH       $DFF048        BLTCPTL       $DFF04A
  185.   D        BLTDPTH       $DFF054        BLTDPTL       $DFF056
  186.  
  187. Chiaramente, queste coppie di registri possono essere trattate come singoli
  188. registri a 32 bit - come per i puntatori alle CopperList ed ai Plane -, e, 
  189. quindi, essere scritti con una singola istruzione "move.l" all'indirizzo
  190. di BLTxPTH. Pertanto d'ora in avanti li considereremo come singoli registri
  191. a 32 bit, usando i nomi di BLTxPT e riferendoci agli indirizzi $dff050,
  192. $dff04c, $dff048 e $dff054 (salvo eventuali eccezioni che verranno
  193. opportunamente segnalate).
  194.  
  195. I registri di puntatore dovrebbero essere scritti con un indirizzo in byte, ma
  196. poichè il blitter lavora solo su WORDS, il bit meno significativo del nostro
  197. indirizzo viene ignorato, dunque occorre ricordare che gli indirizzi devono
  198. essere PARI, ossia allineati a WORDS.
  199. Quindi occorre ricordarsi che si possono scrivere solo indirizzi PARI della
  200. memoria CHIP, sia per le sorgenti che per la destinazione.
  201.  
  202. NOTA: Assegnate i bit non usati a zero, specialmente quelli che non hanno
  203. nessuna funzione nemmeno in ECS, dato che in versioni future potrebbero essere
  204. usati per chissa' quali scopi e i risultati sarebbero imprevedibili.
  205.  
  206. 4) L'ultima operazione da effettuare e` indicare la quantita` di dati che
  207. devono essere letti o scritti. Cio` viene fatto tramite il registro
  208. BLTSIZE ($dff058). Questo registro permette al blitter di considerare i dati
  209. che legge e scrive non come una semplice sequenza di word, ma come una sorta
  210. di rettangolo bidimensionale composto da words. Per esempio il blitter
  211. considera una sequenza di 8 words, come un rettangolo largo 8 words e
  212. alto 1 linea:
  213.  
  214.                            Larghezza=8 WORD
  215.                      _______________|_______________
  216.                     /                               \
  217.  
  218.                    una word
  219.                      _|_
  220.                     /   \ 
  221.                  /  +---+---+---+---+---+---+---+---+
  222. Altezza=1 LINEA -   | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
  223.                  \  +---+---+---+---+---+---+---+---+
  224.  
  225.             fig. 1    rettangolo di words 8*1
  226.  
  227. Facciamo un altro esempio: una sequenza di 50 words puo` essere considerata
  228. come un rettangolo di 10 word X 5 linee:
  229.  
  230.  
  231.                            Larghezza=10 WORD
  232.                      _______________|_______________
  233.                     /                               \
  234.  
  235.                    una word
  236.                      _|_
  237.                     /   \ 
  238.                   / +---+---+---+---+---+---+---+---+---+---+
  239.                  |  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
  240.                  |  +---+---+---+---+---+---+---+---+---+---+
  241.                  |  |   |   |   |   |   |   |   |   |   |   |
  242.                  |  +---+---+---+---+---+---+---+---+---+---+
  243. Altezza=5 LINEE -|  |   |   |   |   |   |   |   |   |   |   |
  244.                  |  +---+---+---+---+---+---+---+---+---+---+
  245.                  |  |   |   |   |   |   |   |   |   |   |   |
  246.                  |  +---+---+---+---+---+---+---+---+---+---+
  247.                  |  |   |   |   |   |   |   |   |   |   |   |
  248.                  \  +---+---+---+---+---+---+---+---+---+---+
  249.  
  250.             fig. 2    rettangolo di words 10*5
  251.  
  252. Questo fatto che a prima vista puo` sembrare un inutile complicazione e` in
  253. realta` una delle caratteristiche che rendono il blitter tanto potente.
  254. Tra un attimo vedremo bene per quale motivo. Prima pero` vediamo come funziona
  255. BLTSIZE. Per specificare la quantita` di dati coinvolta nella blittata, si
  256. scrivono in BLTSIZE le dimensioni del rettangolo di words che i dati formano.
  257. Nei 6 bit bassi va espressa la dimensione orizzontale, ovvero il NUMERO DI
  258. WORD che costituisce ogni linea orizzontale; nei 10 bit alti va espresso
  259. IL NUMERO DI LINEE orizzontali che costituiscono il rettangolo: in sostanza,
  260. nei 6 bit bassi va la larghezza in X del rettangolo, nei 10 bit alti va
  261. l' altezza in Y del suddetto rettangolo.
  262. E' da notare che se il valore dei 10 bit alti (altezza) e' 0,il blitter 
  263. blittera' 1024 linee, e se il valore dei 6 bit bassi (larghezza in word) e' 0,
  264. il blitter blittera' 64 word: la piu' grande blittata, dunque, si ottiene
  265. scrivendo "move.w  #$0000,$dff058".
  266. Essa sara' di 64 word X 1024 linee (=64*2*1024=128 Kb).
  267. Il registro BLTSIZE ha inoltre un'altra importantissima funzione: SCRIVENDOCI
  268. SI ATTIVA IL BLITTER, dando inizio all'operazione specificata.
  269. Per questo motivo, SI DEVE SCRIVERE NEL REGISTRO BLTSIZE SEMPRE DOPO AVER
  270. SCRITTO IN TUTTI GLI ALTRI REGISTRI DEL BLITTER, altrimenti la 
  271. blittata iniziera` prima che voi abbiate settato correttamente tutti i
  272. registri, producendo risultati differenti da quelli voluti.
  273.  
  274.                         ._________________
  275.                         |    _________    |
  276.                         |   (_________)   |
  277.                         |_________________|
  278.                          |:·            ·|
  279.                         _|______   ______|_
  280.                          |______. .______|
  281.                        _/       |^|       \_
  282.                      __\\_______|_|_______//__
  283.                     /__/    __(_____)__    \__\
  284.                    //\/    /           \    \/\\
  285.                    \_/    /_____________\    \_/
  286.                     /    /¯    _____    ¯\    \
  287.                     \        _  /    _        /  ___________
  288.         .____________\_______(       )_______/__/           \
  289.         | ___/                \_____/          / _     _   _ \
  290.         | | \_________________________________/  \|    |   |  \
  291.         | |      g®m|         _________      /    \    |   |   \
  292.       __| |__       |       ¯¯   /|\   ¯¯   /______\___|___|___/
  293.      /       \ _____|___________  |  ______//______\\     )
  294.     (__|_| |_//                 \_|_/      \        /____/
  295.          |_| /___________________\ /_____ __\______/____\
  296.  
  297.  
  298. A questo punto e` bene mettere in pratica quello che si e` appreso sinora,
  299. guardando alcuni esempi. In questi esempi vengono utilizzati anche dei
  300. registri di cui non abbiamo ancora parlato, come BLTDMOD e BLTCON1.
  301. Per il momento ignorateli, li spiegheremo in seguito.
  302.  
  303. In Lezione9a1.s vedrete come cancellare una zona di memoria usando il blitter.
  304. Per eseguire un'operazione di cancellazione e` necessario usare solo il
  305. canale D, in quanto l'unica cosa che dobbiamo fare e` scrivere delle word
  306. azzerate nella memoria. Disabilitando il canale sorgente, nella destinazione
  307. sara' scritto il valore $00.
  308. Inoltre per definire un'operazione di cancellazione e` necessario scrivere
  309. il valore $00 nei MINTERMS, cioe` nei bit 0-7 (il byte basso) del registro
  310. BLTCON0.
  311.  
  312. In lezione9a2.s invece useremo il blitter per copiare dei dati da una zona
  313. di memoria in un'altra. Per questa operazione useremo i canali A e D.
  314. I dati verranno letti dalla memoria tramite il canale A e verranno scritti
  315. tramite il canale D. Per definire un'operazione di copia dal canale A al canale
  316. D e` necessario scrivere il valore $F0 nei MINTERMS.
  317.  
  318.         __________
  319.         \ AMIGA! /       lllll
  320.          \ !!!! /     __/     \__
  321.           \____/      \/ (o!o) \/
  322.             ||        / \_____/ \
  323.             ||       /___________\\\\\
  324.             ||           _| |_     \  \
  325.             ||__________/     \_____\_ \
  326.             ()(________/       \________)
  327.             ||        /_________\
  328.             ||       (_____°_____)
  329.             ||        \    Y    /
  330.             ||       __\___|___/__
  331.           __||____ __\_____!_____/_____
  332.  
  333. *******************************************************************************
  334. *        PRIME APPLICAZIONI DEL BLITTER                      *
  335. *******************************************************************************
  336.  
  337. Ora inizieremo ad usare il blitter in applicazioni grafiche. Sappiamo che
  338. un'immagine e` costituita da word di dati in memoria. Poiche` mediante il
  339. blitter possiamo compiere operazioni sulla memoria, modificando i dati che
  340. costituiscono un'immagine provochiamo una modifica dell'immagine stessa.
  341. Facciamo quindi un breve ripasso sulla rappresentazione delle immagini,
  342. limitandoci per ora al caso di un singolo bit-plane.
  343.  
  344. Un bit-plane e` un insieme di word, ognuna delle quali rappresenta lo stato
  345. di un pixel: una word rappresenta 16 pixel disposti orizzontalmente.
  346. La prima word del bit-plane rappresenta i 16 pixel piu` a sinistra della prima
  347. riga dell'immagine.
  348. Le word seguenti rappresentano in ordine tutti i pixel della prima riga.
  349. Quando sono finiti i pixel della prima riga, si comincia allo stesso modo con
  350. quelli della seconda.
  351. Se su una riga ci sono ad esempio 320 pixel, sono necessarie 320/16=20 word
  352. per rappresentarla tutta; quindi le prime 20 word del bit-plane rappresentano
  353. la prima riga dell'immagine,le word dalla 21-esima alla 39-esima rappresentano
  354. la seconda riga, eccetera:
  355.  
  356.          ____ ____ ____ ____ _ _ _ _ _ _ ____
  357.         |    |    |    |    |        |    |
  358.         | 0  | 1  |  2 |  3 |            | 19 |
  359.         |____|____|____|____|        |____|
  360.         |    |    |    |    |        |    |
  361.         | 20 | 21 | 22 | 23 |        | 39 |
  362.         |____|____|____|____|        |____|
  363.         |    |    |    |    |        |    |
  364.         | 40 | 41 | 42 | 43 |        | 59 |
  365.         |____|____|____|____|        |____|
  366.         |                     |
  367.         |                     |
  368.  
  369.  
  370.         |____ ____ ____ ____         ____|
  371.         |    |    |    |    |        |    |
  372.         |    |    |    |    |        |    |
  373.         |____|____|____|____|_ _ _ _ _ _|____|
  374.  
  375.         Fig. 3  Rappresentazione in memoria di un'immagine:
  376.                 ogni quadrato e` una word
  377.  
  378. Abbiamo visto che con il blitter possiamo copiare dati da un punto all'altro
  379. della memoria. Se copiamo dati all'interno di un bit-plane, i valori da noi
  380. copiati verranno usati per formare l'immagine sullo schermo. Il blitter,
  381. poiche` come abbiamo detto lavora su dati di dimensione WORD (16 bit), ci
  382. permette di modificare l'immagine a gruppi di WORD, cioe` a gruppi di 16 pixel.
  383. Per esempio, se con il blitter scriviamo sopra la 21-esima word del bitplane
  384. mostrato in figura, modificheremo i 16 pixel piu` a sinistra della seconda riga
  385. dell'immagine. Supponiamo ora di avere un'immagine alta una sola riga e larga
  386. un certo numero L di pixel. Proprio per il fatto che il bit-plane e` diviso
  387. in word, che contengono 16 pixel, e` conveniente che la larghezza in pixel
  388. della nostra immagine, cioe` L, sia un numero multiplo di 16, in modo che
  389. l'immagine sia contenuta esattamente in L/16 word. Cio` puo` essere ottenuto
  390. aggiungendo dei pixel di valore 0 alla fine della nostra immagine, come
  391. illustrato dal seguente esempio:
  392.  
  393. Questa e` un'immagine larga 20 pixel e alta una sola riga.
  394.  
  395.     11001101010100011001
  396.     \__________________/
  397.           |
  398.          20 pixel
  399.  
  400. Non e` comoda da gestire perche` 20 non e` un multiplo di 16. Allora
  401. aggiungiamo dei pixel di valore 0 alla fine in modo da rendere la larghezza
  402. pari a 32 pixel, cioe` pari ad un multiplo di 16.
  403.  
  404.     11001101010100011001000000000000
  405.     \______________________________/
  406.         |
  407.         32 pixel
  408.  
  409. La nostra immagine e` memorizzata tra i dati nel nostro programma. Per farla
  410. apparire sullo schermo, dobbiamo copiarla nella zona di memoria dedicata al
  411. bit-plane. L'immagine assumera` sullo schermo una posizione corrispondente
  412. alle word del bit-plane nelle quali la copieremo. Supponiamo di voler disegnare
  413. l'immagine sullo schermo in maniera che il primo pixel di essa, cioe` il pixel
  414. piu` a sinistra, assuma le coordinate X e Y (vi ricordo che il sistema di
  415. coordinate dello schermo ha l'origine, cioe` il punto di coordiante X=0 e Y=0,
  416. nell'angolo superiore sinistro, le coordiante X crescono andando verso destra
  417. mentre le Y crescono andando verso il basso).
  418. Tale pixel sata` contenuto in una word del bit-plane.
  419. Per il momento limitiamoci a considerare il caso in cui X sia anch' esso
  420. multiplo di 16. Cio` ci assicura che il nostro pixel sia il primo (cioe` il
  421. pixel piu` a sinistra) della word a cui appartiene. In questo modo, una volta
  422. calcolato l'indirizzo di tale word, potremo copiarci (con il blitter) la prima
  423. word dell'immagine. Le altre word che formano la nostra immagine verranno
  424. copiate naturalmente nelle successive word del bit-plane.
  425. Tutto questo , visto che il blitter e` in grado di copiare sequenze di word,
  426. si puo` fare con una singola blittata che abbia come indirizzo sorgente la
  427. prima word dell'immagine, e come indirizzo destinazione, l'indirizzo della
  428. word del bit-plane a cui appartiene il pixel di coordinate X e Y.
  429. Vediamo come si fa per calcolare questo indirizzo.
  430. Numeriamo le word del bit-plane a partire da 0, come mostrato in figura, e
  431. calcoliamo il numero della word che ci interessa: da tale numero risaliremo
  432. poi all'indirizzo vero e proprio.
  433. Cominciamo col calcolare il numero della prima word della riga Y, ricordando
  434. ancora una volta che ogni riga e` formata da 20 word e che le righe sono
  435. numerate a partire da 0. Potete notare dalla figura che la prima word della
  436. riga 0 (la prima riga) ha numero 0, la prima word della riga 1 (la seconda
  437. riga) ha numero 20, la prima word della riga 2 ha numero 40, la prima word
  438. della riga 3 ha numero 60 e cosi` via.
  439. In generale quindi, la prima word della riga Y ha numero Y*20.
  440. I numeri delle altre word della riga sono consecutivi a quello della prima:
  441. la seconda word della riga ha numero Y*20+1, la terza word della riga ha
  442. numero Y*20+2 e cosi` via.
  443. Possiamo chiamare "distanza" di una certa word R dalla prima word della riga
  444. cui R appartiene, la quantita` che bisogna aggiungere al numero della prima
  445. word della riga per ottenere il numero della word R: in pratica, poiche` la
  446. seconda word della riga ha numero Y*20+1, diciamo che essa ha "distanza" 1
  447. dalla prima word della riga; allo stesso modo la terza word della riga, che
  448. ha numero Y*20+2 ha distanza 2 dalla prima word della riga, e cosi` via.
  449. Possiamo dire inoltre che la prima word della riga ha distanza 0 da se stessa.
  450. E` molto semplice calcolare la distanza tra la word che contiene il pixel di
  451. coordinata X e la prima word della riga, come vedremo aiutandoci con la
  452. seguente figura:
  453.  
  454.          ________ ________ ________ ________ _ _ _
  455.         |        |        |        |        |        
  456. riga Y        | Y*20+0 | Y*20+1 | Y*20+2 | Y*20+3 |
  457.         |________|________|________|________|_ _ _
  458.  
  459. Distanza
  460. dalla prima 
  461. word        |   0     |   1      |   2    |   3    | -  -
  462.  
  463. Pixel
  464. contenuti:    |  0-15  |  16-31 |  32-47 |  48-63 | -  -
  465.  
  466.             fig. 4    riga di words
  467.  
  468. La coordinata X del nostro pixel rappresenta la distanza (in pixel) tra esso
  469. e il primo pixel della riga. Poiche` ogni word contiene 16 pixel, la prima word
  470. di una riga contiene i primi 16 pixel della riga, cioe` quelli che hanno una
  471. coordinata X (=una distanza dal bordo) da 0 a 15.
  472. La seconda word invece contiene i pixel la cui coordinata X varia da 16 a 31,
  473. la terza word i pixel con X che varia da 32 a 47 e cosi` via: ogni 16 pixel
  474. abbiamo una word.
  475. Quindi per calcolare la distanza tra le word, basta dividere la distanza in
  476. pixel (cioe` il valore di X) per 16. Poiche` abbiamo scelto X multiplo di 16,
  477. il risultato sara` un intero. Per esempio, se X=32, la distanza in word vale
  478. 32/16=2. Infatti, come vedete nella figura il pixel 32 della riga Y e`
  479. il primo pixel della seconda word della riga, il cui numero e` proprio Y*20+1.
  480. Con lo stesso calcolo vediamo che il pixel che ha X=64 e` contenuto nella word
  481. che dista 64/16=4, word il cui numero e` Y*20+3. Questo calcolo funziona anche
  482. se X=0: infatti abbiamo distanza 0/16=0 cioe` la word di numero Y*20+0 che e`
  483. appunto la prima word della riga.
  484.  
  485. In totale, quindi la word che contiene il pixel X,Y  e` la word con numero N
  486. dato dalla seguente formula:
  487.  
  488.     N=(Y*20)+(X/16)
  489.  
  490. Questa formula e` valida per bit-plane nei quali una riga e` formata da 20
  491. word. In generale la formula e`:
  492.  
  493.     N=(Y*NUMERO_WORD_CHE_FORMANO_UNA_RIGA)+(X/16)
  494.  
  495. Dal numero della word possiamo risalire all'indirizzo corrispondente:
  496. basta conoscere l'indirizzo della prima word del bit-plane e aggiungerci il
  497. numero della word moltiplicato per 2 (la moltiplicazione e` necessaria perche`
  498. l'indirizzo e` espresso in byte e 1 word = 2 byte):
  499.  
  500. Indirizzo word=(Indirizzo bitplane)+N*2 .
  501.  
  502. Nell'esempio Lezione9b1.s troverete l'applicazione di tutto quanto abbiamo
  503. detto. Nell'esempio Lezione9b2.s vedrete una serie di blittate in diverse
  504. posizioni dello schermo.
  505.  
  506. Iniziamo ora ad occuparci di immagini che abbiano altezza maggiore di una riga.
  507. Abbiamo visto quando abbiamo parlato del registro BLTSIZE, come il blitter
  508. consideri i dati su cui deve operare come dei "rettangoli" di words. Questa
  509. caratteristica e` molto utile, perche` gli consente di lavorare agevolmente
  510. con immagini rettangolari. Supponiamo ad esempio di voler copiare all'interno
  511. di un bitplane un'immagine larga 32 pixel e alta 2 linee. Questa piccola
  512. immagine andra` ad occupare una piccola porzione del bitplane, evidenziata
  513. nella figura dalle linee oblique.
  514.  
  515.          ____ ____ ____ ____ _ _ _ _ _ _ ____
  516.         |    |    |    |    |        |    |
  517.         | 0  | 1  |  2 |  3 |            | 19 |
  518.         |____|____|____|____|        |____|
  519.         |    |\\\\|\\\\|    |        |    |
  520.         | 20 |\21\|\22\| 23 |        | 39 |
  521.         |____|\\\\|\\\\|____|        |____|
  522.         |    |\\\\|\\\\|    |        |    |
  523.         | 40 |\41\|\42\| 43 |        | 59 |
  524.         |____|\\\\|\\\\|____|        |____|
  525.         |                     |
  526.         |                     |
  527.  
  528.  
  529.         |____ ____ ____ ____         ____|
  530.         |    |    |    |    |        |    |
  531.         |    |    |    |    |        |    |
  532.         |____|____|____|____|_ _ _ _ _ _|____|
  533.  
  534.         Fig. 5  Un bit-plane con evidenziata la porzione
  535.             sulla quale blitteremo
  536.  
  537. Si tratta di un piccolo rettangolo largo 2 words (cioe` 32 pixel) e alto 2
  538. linee. Capirete immediatamente che per effettuare la copia e` necessario
  539. specificare in BLTSIZE le dimensioni del rettangolo. Ma cio` non
  540. e` sufficente. Per rendercene conto, mettiamoci per un momento nei panni del
  541. blitter e proviamo a eseguire noi la copia, puntando la nostra attenzione
  542. per il momento solo sulla fase di scrittura.
  543. Sappiamo (perche` e` scritto in BLTDPT) l'indirizzo della word in alto a
  544. sinistra del rettangolo (la word 21 nella figura). Inoltre sappiamo (e` scritto
  545. in BLTSIZE) le dimensioni del rettangolo da copiare. Molto bene.
  546. Leggiamo la prima word e la copiamo all'indirizzo della word 21.
  547. Ora dobbiamo copiare la seconda word della prima riga. Sappiamo che questa word
  548. e` consecutiva alla prima word, quindi aggiungiamo 2 all'indirizzo della prima
  549. word (che e` scritto in BLTDPT) e sappiamo l'indirizzo della seconda word da
  550. scrivere. La scriviamo e abbiamo finito la prima riga. Molto soddisfatti ci
  551. prepariamo a scrivere la seconda riga. E qui ci accorgiamo che c'e` un piccolo
  552. problema: la prima word della seconda riga NON E` CONSECUTIVA all'ultima word
  553. della prima riga! Infatti come potete vedere dalla figura l'ultima word della
  554. prima riga e` la word 22 mentre la prima della seconda riga e` la word 41.
  555. Come facciamo a calcolare l'indirizzo della prima word della seconda riga?
  556. Nella figura e` rappresentato un bitplane largo 20 word, ma e` solo un esempio.
  557. Come fa il povero blitter a sapere quante word e` largo il bitplane? Infatti
  558. potremmo essere in presenza di un bitplane piu` largo dello schermo visibile!
  559. Anzi a pensarci bene chi l'ha detto al blitter che lo stiamo usando per copiare
  560. un rettangolo sullo schermo? E se invece stessimo semplicemente copiando dei
  561. dati in una copperlist? E` evidente che da solo il blitter non sa trarsi
  562. d'impaccio. Ma non c'e` problema, lo aiutiamo noi. Quello che al blitter serve
  563. di sapere e` semplicemente come fare per calcolare l'indirizzo della prima word
  564. di una riga sapendo l'indirizzo dell'ultima word della riga precedente. Se
  565. guardate un'attimo la figura vi convincerete il blitter deve semplicemente
  566. "saltare" le word da 23 a 40 comprese. Cio` puo` essere fatto aggiungendo
  567. all'indirizzo della word 22 (cioe` l'indirizzo dell'ultima word della prima
  568. riga, che il blitter gia` conosce) il numero di bytes di differenza rispetto
  569. alla word 42 (che e` appunto la prima word della nuova riga). Tale numero di
  570. bytes, che si chiama MODULO, e` ovviamente uguale al numero di words da
  571. "saltare" moltiplicato per 2 (poiche` come ben sapete una word occupa 2 bytes).
  572.  
  573.  
  574. word        0            X            X+L             H
  575. riga y         |------------|*************|--------------|
  576. riga y+1    |------------|*************|--------------|
  577.         \____________/\____________/\_____________/
  578.                |            |            |
  579.           word da    figura         word da
  580.          saltare    larga L        saltare
  581.                 word
  582.  
  583.         Fig. 6    Modulo
  584.  
  585. In generale, se dobbiamo copiare un rettangolo largo L words all'interno
  586. di una bitmap larga H words, il MODULO espresso in bytes si ottiene con
  587. la seguente formula:
  588.  
  589. MODULO = (H-L)*2
  590.  
  591. Il calcolo H-L ci darebbe il modulo espresso in words, la moltiplicazione per 2
  592. serve per esprimerlo in bytes. Nel nostro esempio il MODULO vale (20-2)*2.
  593. Se vi ricordate avevamo gia` incontrato il concetto di modulo relativamente
  594. ai bit-planes. Il modulo del blitter funziona esattamente allo stesso modo.
  595. E` possibile assegnare un modulo diverso per ogni canale DMA. In questo modo
  596. i dati possono essere copiati e spostati fra bitplanes di differenti larghezze.
  597. Il valore del modulo viene scritto in 4 appositi registri, uno per ogni canale
  598. DMA: BLTAMOD per il canale A ($dff064), BLTBMOD per il B ($dff062),
  599. BLTCMOD per il C ($dff060), BLTDMOD per il D ($dff066).I valori del modulo sono
  600. in byte, non words. Siccome il blitter può operare solo su words, il bit meno
  601. significativo è ignorato, questo significa che il valore del modulo deve essere
  602. pari.
  603. Il valore, positivo o negativo, viene aggiunto automaticamente ai registri che
  604. puntano agli indirizzi (BLTxPT) ogni volta che il blitter ha finito di copiare
  605. una riga, in modo da calcolare l'indirizzo della prima word della riga
  606. successiva.
  607. Valori negativi del modulo possono essere utili in molti casi, ad esempio per
  608. ripetere una linea settando il modulo come la larghezza del bitplane al
  609. negativo. Abbiamo gia' visto nella lezione 5 come replicare una linea mettendo
  610. il modulo copper BPL1MOD/BPL2MOD a -40, o comunque -LunghezzaLinea.
  611.  
  612.                   ._________
  613.                   |  _ ____/
  614.                ___|______|___
  615.              _/              \_
  616.              \________________/
  617.                   \_ Oo _/
  618.                 /\_(¯¯¯¯)_/\
  619.                /    \  /    \
  620.              ./ /\   \/   /\ \.))
  621.              | |  \__  __/  | |
  622.              | |   |    |   | |
  623.              | \   |    |   / |
  624.            (( \ \__|____|__/ /
  625.                \/ _/    \_ \/
  626.                 \||______||/
  627.                /|_|  |   |_|\
  628.               / ||   |    || \
  629.              ( (¯    |     ¯) )
  630.              | |     |      | |
  631.              | |     |      | |
  632.             _|_|     |      |_|_
  633.             \  |     |______|  /
  634.              ) |           g| (
  635.          ___/  |           ®|  \___
  636.         /______|           m|______\
  637.  
  638. A questo punto sappiamo come copiare un rettangolo all'interno di una bitmap.
  639. Riassumiamo con un esempio tutti i calcoli necessari:
  640.  
  641. Supponiamo di voler operare su una sezione di un bitmap 320x200, che
  642. inizia alla riga 13, word 6 (dove entrambi sono numerati da zero) larga 5
  643. word. Per prima cosa dobbiamo calcolare l'indirizzo della prima word del
  644. rettangolo, e poi scriverlo nel registro BLTxPT del canale che ci interessa.
  645. Il calcolo viene fatto nel modo seguente: prendiamo l'indirizzo del prima
  646. word del bitplane, aggiungiamo 13*20*2 bytes per calcolare l'indirizzo del
  647. primo byte della riga 13 (infatti ogni riga occupa 20 words=40 bytes) e infine
  648. aggiungiamo 12 byte (=6 words) per arrivare alla giusta posizione orizzontale.
  649. La larghezza e` di 5 words (10 byte). Alla fine di ogni riga, dobbiamo saltare
  650. 30 byte per arrivare all'inizio della riga seguente, quindi usiamo un modulo di
  651. 30. In generale, la larghezza (in words) raddoppiata più il valore modulo (in
  652. byte) dovrebbe equivalere alla piena larghezza, in byte, del bitplane che
  653. contiene l'immagine.
  654.  
  655. Questi calcoli sono illustrati nella figura che mostra i valori richiesti
  656. usati nei registri blitter BLTxMOD e BLTxPTR (BLTxPTH e BLTxPTL).
  657.  
  658.  
  659.    <Mem_Addr> = Indirizzo (0,0)
  660.         \
  661.          \
  662.           \            NUMERO BYTE (COLONNA)
  663.            \
  664.             \ 0        10          20    30     39
  665.          \|         |           |     |      |
  666.           +----------------------------------------+ - -
  667.          0|········································|    |
  668.          1|········································|
  669.          2|········································|    |
  670.          3|········································|
  671.          4|········································|    |
  672.          5|········································|
  673.          6|········································|    |
  674.          7|········································|
  675.          8|········································|    |
  676.          9|········································|
  677.     NUMERO    10|········································|    |
  678.     riga    11|········································|
  679.         12|········································|    |- - finestra
  680.         13|············##########··················|         bitmap
  681.         14|············##########··················|    |
  682.         15|·salto sin. ##########··· salto dest.···|
  683.         16|<---------->##########<---------------->|    |
  684.         17| = 12 bytes ##########··· = 18 bytes ···|
  685.         18|············##########··················|    |
  686.         19|·················\······················|
  687.         20|··················\·····················|    |
  688.          -|···················\····················|
  689.          -|····················\···················|    |
  690.          -|·····················\··················|
  691.          -|······················\·················|    |
  692.           +-----------------------\------------\---+ - -
  693.                        \        \
  694.                         \         \
  695.                 immagine da manipolare      \
  696.                                \
  697.                              un byte
  698.  
  699.     BLTxPTR = <Mem_Addr> + (40*13) + 12
  700.         = <Mem_Addr> + 532
  701.  
  702.     BLTxMOD = 12 + 18
  703.         = 30 bytes
  704.  
  705.         Fig. 7  calcoli per BLTxPTR e BLTxMOD
  706.  
  707. A questo punto e` bene fare una sosta e guardarsi un po' di esempi.
  708.  
  709. In lezione9c1.s e lezione9c2.s trovate semplici esempi di copia di aree
  710. rettangolari. Studiateli attentamente, concentrandovi sul calcolo degli
  711. indirizzi e dei moduli usati nelle blittate.
  712.  
  713. In lezione9c3.s c'e` un esempio nel quale viene effettuata una blittata con
  714. modulo negativo.
  715.  
  716. In lezione9d1.s e lezione9d2.s vedrete i primi esempi di animazione con il
  717. blitter.
  718.  
  719. L'idea e` molto semplice, per dare l'idea del movimento basta disegnare la
  720. nostra figura ogni volta in una posizione diversa, un po' come si faceva con
  721. gli sprites.
  722. Diversamente da allora, pero`, prima di disegnara la figura nella nuova
  723. posizione, dovremo cancellarla dalla vecchia, altrimenti otterremmo un effetto
  724. "scia".
  725. In questi 2 esempi spostiamo di volta in volta la figura in basso di una riga,
  726. aggiungendo ogni volta 40 bytes all'indirizzo BLTxPT.
  727.  
  728. In lezione9d3.s applichiamo la stessa tecnica per spostare la figura in
  729. orizzontale. Notate pero` che modificare l'indirizzo equivale a spostare il
  730. rettangolo a destra (o a sinistra) di una o piu` word. Poiche` una word
  731. corrisponde a 16 pixel, in questo modo possiamo spostare orizzontalmente la
  732. figura solo a scatti di 16 pixel, il che rende, come potete vedere nell'esempio
  733. il movimento poco fluido, e troppo veloce.
  734.  
  735.                   .       :
  736.                           ·
  737.                   ¦:.:.:.:¦
  738.                   l______ |
  739.                   (°X° )  ¯)
  740.                   |C_¯¯__ T___
  741.      ________     l_____¬ l _ \
  742.     (_____   \________T____/ ) \
  743.         (__   ______________/   \
  744.          (____/      /\°         \
  745.                     / /\°         \
  746.                    / /  \°         \
  747.           .·.     / /    \°_________\
  748.         .·   ·. _/  \     ¯\ _..  ¬\  xCz
  749.       .·       (_   _)      \/·:    \____
  750.     .·          `-`-'       /·:      \.  \__
  751.     ····.     .·····       /·:        \:. \ \
  752.         :     :            \·:.        \::.\ \
  753.     ....:..  .:...........  \·::.       \___\ \
  754.                            __\___________\ `-\_)
  755.                           (_____________)
  756.  
  757. Finora ci siamo limitati a disegnare figure con il pixel piu` a sinistra in
  758. una posizione multipla di 16. Per avere un movimento fluido, invece, e`
  759. necessario poter disegnare la figura in una posizione arbitraria dello schermo.
  760. Facciamo un esempio, immaginando di avere l' immagine di un auto che vogliamo
  761. spostare sullo schermo.
  762. Calcolando opportunamente l'indirizzo del rettangolo che la contiene, possiamo
  763. "blittare" la nostra auto a partire da una qualunque delle word che formano lo
  764. schermo. Se la nostra immagine di auto, per esempio, ha lo sportello a 5
  765. pixel dalla sua estrema sinistra, potremo spostarlo, assieme con la macchina,
  766. a 5 pixel dall'inizio di una qualche word dello schermo. Se vogliamo spostarla
  767. verso destra, possiamo "blittarla" a partire dalla word successiva.
  768. Il risultato sarebbe uno "scatto" di 16 pixel ogni volta. Ma se vogliamo far
  769. scorrere quell' auto a destra o a sinistra di un pixel alla volta, o comunque
  770. vogliamo blittarla in una posizione orizzontale che non sia multipla di 16,
  771. come si fa?
  772.  
  773. Dobbiamo fare in modo che i pixel che formano l'immagine vengano copiati
  774. NON a partire dal primo bit della prima word, a partire da un bit arbitrario
  775. all'interno di tale word, come illustrato dalla seguente figura.
  776.  
  777.         copia con X multiplo di 16
  778.  
  779. prima word
  780. sorgente        1 0 0 1 1 0 1 0 1
  781.  
  782.             | | | | | | | | |
  783.             | | | | | | | | |
  784.             v v v v v v v v v
  785. prima word         _ _ _ _ _ _ _ _ _ _
  786. destinazione           |_|_|_|_|_|_|_|_|_|_
  787.  
  788. bit            0 1 2 3 4 5 6 7 8 ..
  789.  
  790.  
  791.         copia con X arbitrario
  792.  
  793. prima word
  794. sorgente               1 0 0 1 1 0 1 0 1
  795.  
  796.                   | | | | | | | | |
  797.                   | | | | | | | | |
  798.                   v v v v v v v v v
  799. prima word         _ _ _ _ _ _ _ _ _ _
  800. destinazione           |_|_|_|_|_|_|_|_|_|_
  801.  
  802. bit            0 1 2 3 4 5 6 7 8 ..
  803.  
  804.         Fig. 8  Shift
  805.  
  806.  
  807. In pratica dobbiamo shiftare i bit che compongono la figura da destra verso
  808. sinistra.
  809. Il blitter possiede degli shifter hardware per i canali A e B, che shiftano a
  810. destra tutti i bit delle word che vengono lette dai canali A e B.
  811. I bit vengono shiftati di numero di posizioni che puo` variare da 0 a 15.
  812. Shiftare di 0 posizioni equivale a non shiftare affatto: tutte le blittate che 
  813. abbiamo visto (e fatto) finora erano blittate con shift di 0 posizioni.
  814. Il valore di shift per il canale A è assegnato con i bit dal 15 al 12 del
  815. registro BLTCON0 ($dff040); il valore di shift del canale B è assegnato con i
  816. bit dal 15 al 12 di BLTCON1 ($dff042). Se vi ricordate finora avevamo sempre
  817. lasciato questi bit al valore 0, che indica appunto uno shift di 0 posizioni.
  818. Il canale C invece e' un proletario, non ha shifter.
  819. (Per chi se lo e' dimenticato, shiftare dei bit significa "scorrere" dei bit
  820.  verso destra o verso sinistra....)
  821. L'operazione di shifting viene eseguita contemporaneamente alla normale
  822. copia e non influenza la velocita` del blitter: qualunque sia il valore di
  823. shift, il tempo impiegato per la blittata e` sempre lo stesso.
  824.  
  825. Grazie allo shift, possiamo disegnare una figura avente il pixel piu` a
  826. sinistra in una posizione X arbitraria. Infatti, calcolando come di consueto
  827. l'indirizzo della destinazione, possiamo disegnare la figura ad una posizione
  828. X multipla di 16. Attivando contemporaneamente lo shifter, possiamo spostarla
  829. ulteriormente verso destra per farle raggiungere la posizione desiderata.
  830. Per esempio, supponiamo che si voglia una posizione X di 38 pixel.
  831. Mediante il calcolo dell'indirizzo possiamo spostare la figura 32 pixel
  832. (32 e` multiplo di 16) a destra del bordo,0 e possiamo spostarci a destra di
  833. altri 6 bits (38-32=6) impostando uno shift di 6.
  834. In generale se X non e` multiplo di 16, facendo la divisione intera X/16
  835. otteniamo un risultato intero (che usiamo per calcolare l'indirizzo
  836. destinazione) e un resto che ci dice di quanto deve essere lo shift.
  837. (Ricordo che la divisione intera e` una divisione nella quale non vengono
  838. calcolate le cifre decimali del risultato e viene ottenuto un resto, come si
  839. fa in prima elementare; per esempio 7/3=2 col resto di 1).
  840. Nel caso di una posizione orizzontale X=100, abbiamo 100/16=6 con il resto di
  841. 4 (infatti 16*6=96 e 100-96=4); dunque la distanza tra la prima word
  842. destinazione e la prima word della riga e` pari a 6 words, ossia 12 bytes, e
  843. il valore di shift e` di 4 bit.
  844.  
  845. Prima di iniziare ad usare lo shift dobbiamo pero` capire bene come funziona.
  846. Per cominciare, alcuni bit naturalmente sono shiftati a destra fuori delle word
  847. a cui appartenevano. Da sinistra deve essere shiftato dentro qualcosa per
  848. rimpiazzare i bit usciti. Cosa in particolare ? Per la prima word della
  849. blittata, sono shiftati dentro degli zeri; per ogni successiva word della
  850. stessa blittata, i bit shiftati dentro una word sono quelli shiftati fuori
  851. dalla word precedente. Insomma, quello che esce da una parte (la destra)
  852. rientra dall'altra (sinistra!) nella word seguente.
  853. Facciamo un piccolo esempio, aiutandoci con una figura per capirlo meglio.
  854. Supponiamo di copiare 3 words (possono formare un rettangolo alto una riga e
  855. largo 3 word, oppure alto 3 righe larghe 1 word, non fa differenza dal punto di
  856. vista dello shift), applicando un valore di shift pari a 3.
  857. Guardiamo cosa succede:
  858.  
  859. SORGENTE
  860.  word 1             word 2             word 3
  861. 1000110001010101    0001001001000110    1010101010101010
  862.  
  863. DESTINAZIONE
  864.  word 1             word 2             word 3
  865. 0001000110001010    1010001001001000    1101010101010101
  866. ^^^            ^^^            ^^^
  867. questi 3 bit sono gli    questi sono i 3 bit    questi sono i 3 bit
  868. zeri shiftati dentro    shiftati fuori dalla    shiftati fuori dalla
  869. la prima word        prima word e rientrati    word 2 e rientrati
  870.             nella seconda word    nella word 3
  871.  
  872.         Fig. 9  shift
  873.  
  874.  
  875. Notate che gli ultimi 3 bit della word 3 della sorgente NON vengono
  876. copiati da NESSUNA PARTE!
  877.  
  878. Ad esempio, consideriamo una blittata larga tre words e alta due words, con uno
  879. shift di 4 bit. Per semplicità, assumiamo che sia una copia normale da A a D.
  880. La prima word che sarà scritta in D è la prima word presa da A, shiftata a
  881. destra di quattro bit con 4 bit azzerati shiftati dentro dalla sinistra.
  882. La seconda word sarà la seconda word presa da A, shiftata a destra, con i
  883. quattro bit meno significanti (a destra) della prima word shiftati dentro.
  884. Dopo, scrivera' la prima word della seconda riga presa da A, shiftata quattro
  885. bit, con i quattro bit meno significativi dell'ultima word dalla prima riga
  886. shiftati dentro. Questo continuera' finchè la blittata non è terminata.
  887.  
  888. In lezione9e1.s potete vedere un esempio di uso dello shift, che permette ad
  889. una figura di muoversi di un pixel alla volta verso destra. Il risultato pero`
  890. non e` molto buono a causa del fatto che i bit che vengono shiftati fuori
  891. da una word, vengono shiftati dentro la word successiva, che si trova una
  892. riga piu` in basso. Quindi i bit che escono a destra rientrano da sinistra
  893. nella riga successiva! La situazione e` illustrata dalla seguente figura,
  894. assumendo uno shift di 4 bit: 
  895.  
  896.  
  897. SORGENTE
  898. word 1        1000001111100000
  899.   "  2        1100111111111000
  900.   "  3        1111111111101100
  901.   "  4        1111111111111110
  902.   "  5        1100111111111000
  903. word 6        1000001111100000
  904.  
  905.  
  906. DESTINAZIONE
  907. word 1        0000100000111110
  908.   "  2        0000110011111111
  909.   "  3        1000111111111110
  910.   "  4        1100111111111111
  911.   "  5        1110110011111111
  912. word 6        1000100000111110
  913.         ^^^^
  914.         queste 4 colonne di bit sono costituite dai bit entrati da
  915.         sinistra: come vedete (tranne che per la prima riga) in ogni
  916.         riga entrano i bit usciti dalla riga precedente.
  917.  
  918.         Fig. 10  Shift di un rettangolo
  919.  
  920. Fortunatamente questo problema si risolve in modo molto semplice.
  921. Se ci pensate bene, quello che noi vorremmo, e` che i bit che escono a destra
  922. da una word, rientrino da sinistra NON nella riga successiva, ma piuttosto
  923. NELLA WORD PIU` A DESTRA! Dobbiamo quindi "coinvolgere" nella blittata
  924. anche le word piu` a destra. Cio` si puo` fare semplicemente aumentando
  925. la larghezza della figura aggiungendo a destra una "colonna" di word DI
  926. VALORE ZERO. In questo modo, la colonna in piu` e` invisibile, ed inoltre
  927. i bit shiftati fuori dalle word che la compongono saranno tutti zeri e percio`
  928. non daranno fastidio rientrando nelle word della riga seguente.
  929. Per chiarirvi le idee ecco cosa succede:
  930.  
  931. SORGENTE
  932.         word 1        word 2
  933. riga 1        10000011111000000000000000000000
  934.   "  2        11001111111110000000000000000000
  935.   "  3        11111111111011000000000000000000
  936.   "  4        11111111111111100000000000000000
  937.   "  5        11001111111110000000000000000000
  938.   "  6        10000011111000000000000000000000
  939.                 ^^^^^^^^^^^^^^^^
  940.                 Questa e` la colonna di words aggiunta
  941.  
  942. DESTINAZIONE
  943.         word 1        word 2
  944. riga 1        00001000001111100000000000000000
  945.   "  2        00001100111111111000000000000000
  946.   "  3        00001111111111101100000000000000
  947.   "  4        00001111111111111110000000000000
  948.   "  5        00001100111111111000000000000000
  949.   "  6        00001000001111100000000000000000
  950.         ^^^^        ^^^^
  951.         |        Questi 4 bit sono usciti dalla word 1
  952.         |        e sono entrati nella word 2
  953.         |        
  954.         Questi 4 bit sono usciti dalla word 2 della riga precedente e
  955.         entrati nella word 1 (tranne quelli entrati nella word 1 della
  956.         riga 1, che sono azzerati automaticamente)
  957.  
  958.         Fig. 11  Shift di un rettangolo
  959.  
  960. Nell'esempio lezione9e2.s vedrete applicata questa tecnica, che consente di
  961. spostare una figura verso destra di un numero di pixel compreso tra 1 e 15
  962. (infatti i valori di shift possibili vanno da 0 a 15 compresi). 
  963. Nell'esempio lezione9e3.s finalmente vediamo la nostra figura spostarsi verso
  964. destra un numero arbitrario di pixel. In pratica vengono combinati insieme gli
  965. esempi lezione9d3.s e lezione9e2.s
  966.  
  967.                          __---__
  968.                       _-       _--______
  969.                   __--( /     \ )XXXXXXXXXXXXX_
  970.                 --XXX(   O   O  )XXXXXXXXXXXXXXX-
  971.                /XXX(       U     )        XXXXXXX\
  972.              /XXXXX(              )--_  XXXXXXXXXXX\
  973.             /XXXXX/ (      O     )   XXXXXX   \XXXXX\
  974.             XXXXX/   /            XXXXXX   \__ \XXXXX----
  975.             XXXXXX__/          XXXXXX         \__-----
  976.     ---___  XXX__/          XXXXXX      \__         ---
  977.       --  --__/   ___/\  XXXXXX            /  ___---=
  978.         -_    ___/    XXXXXX              '--- XXXXXX
  979.           --\/XXX\ XXXXXX                      /XXXXX
  980.             \XXXXXXXXX                        /XXXXX/
  981.              \XXXXXX                        _/XXXXX/
  982.                \XXXXX--__/              __-- XXXX/
  983.                 --XXXXXXX---------------- XXXXX--
  984.                    \XXXXXXXXXXXXXXXXXXXXXXXX-
  985.                      --XXXXXXXXXXXXXXXXXX-
  986.  
  987. *******************************************************************************
  988. *        BLITTATE "A COLORI"                          *
  989. *******************************************************************************
  990.  
  991. Fino a questo momento ci siamo limitati a considereare immagini formate da un
  992. solo bitplane, cioe` a 2 soli colori. Normalmente, quando si lavora con
  993. immagini a piu` colori, si dispongono i bit-plane consecutivamente in memoria,
  994. in modo che subito dopo l'ultima word di un bit-plane ci sia la prima word del
  995. bit-plane successivo.
  996. L'immagine risulta quindi strutturata nel modo seguente:        
  997.  
  998.          ____ ____ ____ ____ _ _ _ _ _ _ ____
  999. bitplane 1    |    |    |    |    |        |    |
  1000.         | 0  | 1  |  2 |  3 |            | 19 |    riga 0 bitplane 1
  1001.         |____|____|____|____|        |____|
  1002.         |    |    |    |    |        |    |
  1003.         | 20 | 21 | 22 | 23 |        | 39 |    riga 1 bitplane 1
  1004.         |____|____|____|____|        |____|
  1005.         |                     |
  1006.         |                     |
  1007.  
  1008.  
  1009.         |____ ____ ____ ____         ____|
  1010.         |    |    |    |    |        |    |
  1011.         |    |    |    |    |        |    |    ultima riga bitplane 1
  1012.         |____|____|____|____|_ _ _ _ _ _|____|
  1013. bitplane 2    |    |    |    |    |        |    |
  1014.         | 0  | 1  |  2 |  3 |            | 19 |    riga 0 bitplane 2
  1015.         |____|____|____|____|        |____|
  1016.         |                     |
  1017.         |                     |
  1018.  
  1019.  
  1020.         |____ ____ ____ ____         ____|
  1021.         |    |    |    |    |        |    |
  1022.         |    |    |    |    |        |    |    ultima riga bitplane 2
  1023.         |____|____|____|____|_ _ _ _ _ _|____|
  1024. bitplane 3    |    |    |    |    |        |    |
  1025.         |    |    |    |    |        |    |    riga 0 bitplane 3
  1026.         |____|____|____|____|_ _ _ _ _ _|____|
  1027.         |                     |
  1028.  
  1029.  
  1030.         |____ ____ ____ ____         ____|
  1031.         |    |    |    |    |        |    |    ultima riga
  1032.         |    |    |    |    |        |    |    dell'ultimo bitplane
  1033.         |____|____|____|____|_ _ _ _ _ _|____|
  1034.  
  1035.         Fig. 12  Rappresentazione in memoria di un'immagine
  1036.              a piu` bitplane (ogni quadrato e` una word)
  1037.  
  1038.  
  1039. Come gia` sapete, un bit-plane largo H words e alto V righe, occupa H*V
  1040. words, ovvero 2*H*V bytes (normalmente H=20 e V=256, quindi un bit-plane
  1041. occupa 40*256 bytes). Questo significa che, poiche` i bit-plane sono disposti
  1042. in memoria uno di seguito all'altro, se il bit-plane 1 inizia all'indirizzo
  1043. PLANE1, il bit-plane 2 iniziera` all'indirizzo PLANE2=PLANE1+2*H*V.
  1044. Analogamente il bit-plane 3 inizia all'indirizzo PLANE3=PLANE2+2*H*V e cosi`
  1045. via. La stessa formula vale per determinare l'indirizzo di una word del
  1046. secondo bit-plane conoscendo l'indirizzo della word corrispondente del
  1047. primo bit-plane: per esempio la settima word del primo bit-plane ha
  1048. indirizzo INDIRIZZO1 = PLANE1+2*7, mentre la settima word del secondo bit-plane
  1049. ha indirizzo INDIRIZZO2 = PLANE2+2*7 = PLANE1+2*H*V+2*7. Ma siccome
  1050. PLANE1+2*7 = INDIRIZZO1, abbiamo la seguente formula:
  1051.  
  1052. INDIRIZZO2 = INDIRIZZO1+2*H*V.
  1053.  
  1054. Questa formula ci sara` molto utile tra poco. Un immagine rettangolare
  1055. contenuta in uno schermo con N bitplane, sara` costituita da N rettangoli,
  1056. uno per bitplane. Quindi, per manipolarla con il blitter, basta eseguire una
  1057. blittata per ogni bit-plane. Nella figura sottostante potete vedere uno
  1058. schermo con 3 bitplane, con evidenziata un'immagine alta 3 righe.
  1059. In memoria, le righe di ogni bitplane, costituiscono un diverso rettangolo
  1060. di words (abbiamo indicato in ogni riga dell'immagine il bitplane a cui essa
  1061. appartiene). Come vedete le righe di ogni bitplane sono vicine tra loro e
  1062. distanti dalle righe degli altri planes, pertanto devono essere manipolate
  1063. con blittate diverse.
  1064.  
  1065.           +----------------------------------------+
  1066.           |········································|
  1067.           |········································|
  1068.           |········································|
  1069.           |········································|
  1070.           |············#####1####··················|
  1071.           |············#####1####··················|
  1072.           |············#####1####··················|
  1073.           |········································|
  1074.  
  1075.           |········································|
  1076.           +----------------------------------------+
  1077.           |········································|
  1078.           |········································|
  1079.           |········································|
  1080.           |········································|
  1081.           |············#####2####··················|
  1082.           |············#####2####··················|
  1083.           |············#####2####··················|
  1084.           |········································|
  1085.  
  1086.           |········································|
  1087.           +----------------------------------------+
  1088.           |········································|
  1089.           |········································|
  1090.           |········································|
  1091.           |········································|
  1092.           |············#####3####··················|
  1093.           |············#####3####··················|
  1094.           |············#####3####··················|
  1095.           |········································|
  1096.  
  1097.           |········································|
  1098.           +----------------------------------------+ 
  1099.  
  1100.         Fig. 13     Schermo con evidenziata un'immagine.
  1101.  
  1102. Per esempio, se abbiamo una figura da disegnare sullo schermo, prima blittiamo
  1103. il primo plane della figura nel primo plane dello schermo, poi il secondo
  1104. plane della figura nel secondo plane dello schermo, poi facciamo lo stesso
  1105. con il terzo plane e via via con gli altri. Di solito quindi si fa un loop di
  1106. blittate, tipo il seguente:
  1107.  
  1108.     move.w    #NUMEROPLANES-1,d1    ; contatore del loop
  1109. LOOP:
  1110. waitblit:            ; aspetta che il blitter abbia finito
  1111.     btst    #6,2(a5)    ; la blittata precedente
  1112.     bne.s    waitblit
  1113.  
  1114.     move.l    #$09f00000,$40(a5)    ; bltcon0 e BLTCON1 - copia da A a D
  1115.  
  1116. ;    carica gli altri registri del blitter
  1117.  
  1118. ;    avvia la blittata
  1119.  
  1120.     dbra    d1,LOOP        ; fai il loop
  1121.  
  1122. I valori da caricare nei registri del blitter sono sempre gli stessi ad
  1123. ogni blittata, tranne ovviamente per quanto riguarda i registri BLTxPT,
  1124. perche` gli indirizzi dei vari bit-plane sono diversi. A questo punto
  1125. entra in gioco la formula che abbiamo visto. Mediante tale formula
  1126. infatti, conoscendo gli indirizzi da scrivere nei registri BLTxPT per la prima
  1127. blittata (cioe` per la blittata relativa al primo bit-plane), siamo in grado di
  1128. calcolare gli indirizzi da scrivere nei registri BLTxPT per le blittate
  1129. successive (cioe` relative ai bit-plane successivi). E` sufficente mettere
  1130. in una variabile l'indirizzo relativo al primo bit-plane, e di aggiungere
  1131. a tale indirizzo 2*H*V ad ogni loop.
  1132.  
  1133. Nell'esempio lezione9f1.s potete vedere questa tecnica applicata. Non sempre
  1134. comunque si usano loop di questo tipo.
  1135.  
  1136. Negli esempi lezione9f2.s e lezione9f3.s ci sono altri esempi di blittate
  1137. "a colori".
  1138.  
  1139. Esiste pero` un'altro modo di disporre in memoria i bitplane, che ci consente
  1140. di blittare in un colpo solo tutti i bitplanes di un'immagine, chiamato
  1141. "INTERLEAVED BITMAP" ovvero "bitmap" interlacciata. Come suggerito dal nome,
  1142. questa tecnica consiste nel "mischiare" tra loro le righe dei vari planes.
  1143. Invece di mettere prima tutte le righe del primo plane, poi quelle del secondo
  1144. e cosi` via, mettamo prima la riga 0 (la prima) del primo bitplane, poi la
  1145. riga 0 del secondo bitplane e poi in ordine le righe 0 degli altri planes;
  1146. dopo le righe 0 di tutti i planes, mettiamo la riga 1 del primo plane, poi la
  1147. riga 1 del secondo, e poi tutte le righe 1 degli altri planes; poi continuiamo
  1148. cosi` con le altre righe. Per capirlo bene guardate la figura seguente e
  1149. confrontatela con la figura 12 dove e` illustrata la disposizione normale
  1150. dei bit-planes.
  1151.  
  1152.  
  1153.          ____ ____ ____ ____ _ _ _ _ _ _ ____
  1154.         |    |    |    |    |        |    |
  1155.         | 0  | 1  |  2 |  3 |            | 19 |    riga 0 bitplane 1
  1156.         |____|____|____|____|        |____|
  1157.         |    |    |    |    |        |    |
  1158.         | 20 | 21 | 22 | 23 |        | 39 |    riga 0 bitplane 2
  1159.         |____|____|____|____|        |____|
  1160.         |                     |
  1161.         |                     |
  1162.  
  1163.  
  1164.         |____ ____ ____ ____         ____|
  1165.         |    |    |    |    |        |    |
  1166.         |    |    |    |    |        |    |    riga 0 ultimo bitplane
  1167.         |____|____|____|____|_ _ _ _ _ _|____|
  1168.         |    |    |    |    |        |    |
  1169.         |    |    |    |    |            |    |    riga 1 bitplane 1
  1170.         |____|____|____|____|        |____|
  1171.         |    |    |    |    |        |    |
  1172.         |    |    |    |    |            |    |    riga 1 bitplane 2
  1173.         |____|____|____|____|        |____|
  1174.         |                     |
  1175.         |                     |
  1176.  
  1177.  
  1178.         |____ ____ ____ ____         ____|
  1179.         |    |    |    |    |        |    |
  1180.         |    |    |    |    |        |    |    riga 1 ultimo bitplane
  1181.         |____|____|____|____|_ _ _ _ _ _|____|
  1182.         |                     |
  1183.         |                     |
  1184.  
  1185.  
  1186.         |____ ____ ____ ____         ____|
  1187.         |    |    |    |    |        |    |
  1188.         |    |    |    |    |        |    |    ultima riga bitplane 1
  1189.         |____|____|____|____|_ _ _ _ _ _|____|
  1190.         |    |    |    |    |        |    |
  1191.         |    |    |    |    |            |    |    ultima riga bitplane 2
  1192.         |____|____|____|____|        |____|
  1193.         |                     |
  1194.  
  1195.  
  1196.         |____ ____ ____ ____         ____|
  1197.         |    |    |    |    |        |    |    ultima riga
  1198.         |    |    |    |    |        |    |    dell'ultimo bitplane
  1199.         |____|____|____|____|_ _ _ _ _ _|____|
  1200.  
  1201.         Fig. 14  Rappresentazione in memoria di un'immagine
  1202.              a piu` bitplane (ogni quadrato e` una word)
  1203.              con la tecnica INTERLEAVED (o RAWBLIT).
  1204.  
  1205. Innanzitutto vediamo come si possono visualizzare immagini in questo formato,
  1206. lasciando da parte un'attimo il blitter. La quantita` di words che compongono
  1207. le righe e` sempre la stessa. Quello che cambia e` la disposizione relativa
  1208. delle righe. Cio` per noi comporta 2 modifiche alla procedura che usiamo
  1209. di solito per visualizzare i bitplanes. La prima riguarda il modo in cui
  1210. calcoliamo gli indirizzi da mettere nei registri BPLxPT.
  1211. Normalmente, per puntare i bitplane nela copper list, calcoliamo gli indirizzi
  1212. dei bitplane successivi al primo, a partire dall'indirizzo del primo,
  1213. aggiungendo ad esso ogni volta il numero di bytes occupati da una riga,
  1214. moltiplicato per il numero di righe che formano il bitplane.
  1215. Questo perche` la prima riga di un bitplane e` memorizzata dopo l'ultima del
  1216. bit-plane precedente, e quindi "dista" dalla prima riga del bit-plane
  1217. precedente un numero di righe pari all'altezza del bitplane stesso.
  1218. Con la disposizione interleaved, invece, la riga o di un bitplane e`
  1219. memorizzata subito dopo la riga 0 del bitplane che lo precede.
  1220. Questo vuol dire che nel loop che calcola gli indirizzi dei bitplane dovremo
  1221. aggiungere ogni volta all'indirizzo di un bitplane semplicemente il numero di
  1222. bytes occupati da UNA riga, per ottenere l'indirizzo del bitplane seguente.
  1223. Dobbiamo osservare inoltre che, a differenza del caso normale, le righe che
  1224. formano un bitplane NON sono disposte consecutivamente in memoria.
  1225. Infatti, tra la riga Y e la riga Y+1 ci sono le righe degli altri bitplane.
  1226. Cio` significa che il puntatore al bitplane, ogni volta che arriva alla fine di
  1227. una riga, deve "saltare" le righe degli altri bitplanes, per andare a puntare
  1228. l'inizio della prossima riga.
  1229. Come avrete gia` intuito, per farlo saltare dobbiamo utilizzare il modulo.
  1230. Vi ricordo infatti che anche i bitplanes hanno i loro moduli, contenuti nei
  1231. registri BPLxMOD (dove x=1 per i bitplanes dispari e x=2 per i pari).
  1232. Con la disposizione normale dei bitplanes, siccome subito dopo la fine di una
  1233. riga inizia la riga successiva, mettiamo il modulo a 0 (a meno che non vogliamo
  1234. fare l'effetto flood o abbiamo un'immagine piu` grande dello schermo).
  1235. Vediamo invece il valore da mettere con la disposizione interleaved.
  1236. Indichiamo con N il numero di bitplane che usiamo.
  1237. Consideriamo il bitplane 1: all'inizio della riga Y il registro BPLPT1 punta
  1238. alla prima word della riga Y del bitplane 1.
  1239. Mentre la riga Y viene visualizzata sul monitor, il registro BPLPT1 si
  1240. sposta puntando le words seguenti.
  1241. Alla fine della riga Y, BPLPT1 punta alla prima word della riga Y del
  1242. bitplane2.
  1243. A questo punto gli viene sommato il modulo.
  1244. Noi vogliamo che BPLPT1 vada a puntare la prima word della riga Y+1 del
  1245. bitplane 1.
  1246. Dobbiamo quindi far saltare al puntatore le righe 2,3,ecc. fino a N.
  1247. In totale si tratta di N-1 righe (per esempio se abbiamo 4 bitplane, dobbiamo
  1248. saltare la riga Y dei bitplanes 2, 3 e 4, cioe` 3 righe).
  1249. Quindi se una riga occupa L words, ovvero 2*L bytes, il valore corretto del
  1250. modulo e` 2*L*(N-1).
  1251.  
  1252.          ____ ____ ____ ____ _ _ _ _ _ _ ____
  1253.         |    |    |    |    |        |    |
  1254.         |    |    |    |    |            |    |    riga Y bitplane 1
  1255.         |____|____|____|____|        |____|
  1256.     /    |    |    |    |    |        |    |
  1257.     |    |    |    |    |    |        |    |    riga Y bitplane 2
  1258.     |    |____|____|____|____|        |____|
  1259.     |    |                     |
  1260.     |    |                     |
  1261.     |
  1262.     |
  1263.  dobbiamo saltare
  1264.  queste N-1 righe
  1265.     |
  1266.     |
  1267.     |    |____ ____ ____ ____         ____|
  1268.     |    |    |    |    |    |        |    |
  1269.     |    |    |    |    |    |        |    |    riga Y bitplane N
  1270.     \    |____|____|____|____|_ _ _ _ _ _|____|
  1271.         |    |    |    |    |        |    |
  1272.         |    |    |    |    |            |    |    riga Y+1 bitplane 1
  1273.         |____|____|____|____|        |____|
  1274.  
  1275.         Fig. 15 Valore del modulo con la tecnica INTERLEAVED.
  1276.  
  1277.  
  1278. Naturalmente tutte le immagni che voliamo visualizzare sullo schermo dovranno 
  1279. avere i bitplane disposti nel formato interleaved. Se un immagine e` definita
  1280. direttamente nel nostro sorgente (tramite delle DC.w ...) , dobbiamo disporre
  1281. le righe come previsto dal formato. Se invece vogliamo tenere l'immagine in un
  1282. file esterno da includere con la direttiva INCBIN, dobbiamo convertirla NON
  1283. in formato RAW (che e` il formato normale) ma in formato interleaved. Tutti
  1284. i programmi di conversione supportano questo formato, anche se molti lo
  1285. chiamano con altri nomi. In particolare il KEFRENS CONVERTER che abbiamo usato
  1286. nel corso, chiama questo formato "RAW-BLIT". Altri converter lo chiamano
  1287. "RASTER MODULO". Fate quindi attenzione a convertire l'immagine nel giusto
  1288. formato, altrimenti non vedrete nulla e passerete ore a cercare nel vostro
  1289. programma un BUG inesistente !
  1290.  
  1291. In lezione9g1.s vedete un esempio di visualizzazione di una bitmap interleaved.
  1292.                        ___
  1293.                      _/   ¬\
  1294.                     /      .¬\
  1295.                    /._/\\_\ \ \
  1296.                   (( _/\__\\ \<
  1297.                   /\/__.  \_.  \
  1298.                  <__ \ø\\__Y\\  \
  1299.               ____<   ¯¯___///  /
  1300.              /ø   Y       .//  /
  1301.             //    |_  ÷---|` ./
  1302.            /`      /\__  ^/\ |
  1303.           /.    .  [_  \_/  \|
  1304.         .//   _/     \_/ ~\  
  1305.         |(    |        ,   \
  1306.         |?    | (   . /    ))
  1307.         |·    | ø    Y    //  _
  1308.         |  _  | ?    |   / \ (%)
  1309.         | |_| | |    ?  ` /"XI_I_ 
  1310.         ?_| |_? ?    ·\  ` [____¬\
  1311.         /?? ??\ ·      \_  [____ (
  1312.         )     ( ._   _.  \_[_____/
  1313.         \_____/   \_/      |÷aXe÷|
  1314.                            X_____X
  1315.  
  1316. Vediamo ora perche` questo formato e` conveniente nell'uso del blitter.
  1317. Nella figura seguente, viene mostrato uno schermo interleaved con evidenziata
  1318. al suo interno un'area rettangolare. Come potete vedere, le righe che formano
  1319. i vari bitplanes sono "mischiate" tra loro, e formano un'unico rettangolo in
  1320. memoria (abbiamo indicato in ogni riga dell'immagine il bitplane a cui essa
  1321. appartiene). Confrontate questa figura con la figura 13 che mostrava una
  1322. situazione analoga in uno schermo "normale". Nel caso normale, le righe degli N
  1323. bitplanes dell'immagine, formano N distinti rettangoli di words, ognuno alto
  1324. tante righe quante sono le righe dell'immagine. Nel caso interleaved invece,
  1325. le righe degli N bitplanes, mischiandosi, formano un unico rettangolo di word.
  1326. Notate che questo rettangolo ha altezza pari all'altezza dell'immagine
  1327. moltiplicata per il numero di bitplanes che la formano. Nella figura
  1328. abbiamo infatti un'immagine di 3 bitplanes alta 3 linee.
  1329. Il rettangolo di words ha 9 righe.
  1330.  
  1331.           +----------------------------------------+
  1332.           |········································|
  1333.           |········································|
  1334.           |········································|
  1335.           |········································|
  1336.           |········································|
  1337.           |········································|
  1338.           |········································|
  1339.           |········································|
  1340.           |········································|
  1341.           |········································|
  1342.           |········································|
  1343.           |········································|
  1344.           |············#####1####··················|
  1345.           |············#####2####··················|
  1346.           |············#####3####··················|
  1347.           |············#####1####··················|
  1348.           |············#####2####··················|
  1349.           |············#####3####··················|
  1350.           |············#####1####··················|
  1351.           |············#####2####··················|
  1352.           |············#####3####··················|
  1353.           |········································|
  1354.  
  1355.           |········································|
  1356.           |········································|
  1357.           |········································|
  1358.           +----------------------------------------+
  1359.  
  1360.         Fig. 16     Schermo INTERLEAVED con evidenziata un'immagine.
  1361.  
  1362. Il fatto che nel formato interleaved le righe dei bitplanes di un'immagine
  1363. formino un unico rettangolo in memoria, e` molto importante perche` ci consente
  1364. di operare sull'immagine mediante una sola blittata. Naturalmente, questa
  1365. blittata e` diversa dalle blittate che facciamo nel caso normale.
  1366. Innanzitutto, e` diversa la dimensione della blittata.
  1367. Infatti nel caso normale ogni blittata ha altezza pari all'altezza
  1368. dell'immagine, mentre nel caso interleaved il rettangolo di words ha
  1369. un'altezza pari all'altezza dell'immagine moltiplicata per il numero di
  1370. bitplanes che la formano, e quindi tale deve essere l'altezza della nostra
  1371. blittata.
  1372. In secondo luogo, e` diverso il modo in cui calcoliamo gli indirizzi delle
  1373. blittate, in particolare dobbiamo cambiare il modo di calcolare l'indirizzo
  1374. della prima word di una riga.
  1375. Nel caso normale, abbiamo visto che se il rettangolo da blittare inizia alla
  1376. riga Y, la "distanza" (offset) della prima word della riga Y dall'inizio
  1377. del bitplane e` pari a Y*(NUMERO DI BYTES OCCUPATI DA UNA RIGA).
  1378. E questo e` logico, perche` in uno schermo normale le righe di un bitplane
  1379. sono consecutive in memoria.
  1380. In uno schermo INTERLEAVED, invece, le cose sono diverse perche` le righe di
  1381. un bitplane non sono consecutive.
  1382. Infatti, come sapete, dopo la riga Y del primo bitplane, ci sono le righe Y
  1383. degli altri bitplane, e dopo di esse la riga Y+1 del primo bitplane.
  1384. Quindi, la distanza tra la prima word della riga Y del primo bitplane e la
  1385. prima word della riga Y+1 del primo bitplane, e` uguale al numero di bytes
  1386. occupati dalle righe Y di tutti i bitplane della figura.
  1387. Con lo stesso ragionamento capite facilmente che la distanza tra la prima word
  1388. della riga Y del primo bitplane e l'inizio dello schermo e` pari a:
  1389.  
  1390.     Y*(NUMERO_DI_BYTES_OCCUPATI_DA_UNA_RIGA)*(NUMERO_DI_PLANES)
  1391.  
  1392. In conclusione, quindi, il calcolo dell'indirizzo per blittare un rettangolo
  1393. che inizia alle coordinate X e Y per uno schermo INTERLEAVED diventa:
  1394.  
  1395. Indirizzo_word = (Indirizzo_bitplane)+N*2
  1396.  
  1397. con:
  1398.     N=(Y*(NUMERO_WORD_CHE_FORMANO_UNA_RIGA)*(NUMERO_PLANES))+(X/16).
  1399.  
  1400. Fare una sola blittata invece che tante, oltre a rendere piu` semplice il
  1401. programma, lo rende anche piu` veloce.
  1402. Si badi bene che il tempo impiegato dal blitter e` (piu` o meno) lo stesso,
  1403. in quanto e` vero che facciamo una sola blittata, ma essa ha altezza pari alla
  1404. somma delle altezze delle blittate del caso normale, e quindi richiede lo
  1405. stesso tempo, perche` la velocita` del blitter e` determinata in sostanza dal
  1406. numero di words che esso deve manipolare, e cioe` dalla dimensione della
  1407. blittata.
  1408. Fare una sola blittata, pero`, avvantaggia notevolmente il processore, come
  1409. potete capire dal seguente schema, che confronta le operazioni da effettuare
  1410. nei 2 casi (schermo formato da 3 bitplanes):
  1411.  
  1412.     SCHERMO NORMALE                SCHERMO INTERLEAVED
  1413.  
  1414. 1)    attendi la fine                attendi la fine
  1415.     della (eventuale) blittata        della (eventuale) blittata
  1416.     precedente                precedente
  1417.  
  1418. 2)    carica i registri del            carica i registri del
  1419.     blitter per la prima            blitter per la prima
  1420.     blittata                e unica blittata
  1421.  
  1422. 3)    attendi la fine
  1423.     della prima blittata
  1424.  
  1425. 4)    carica i registri del
  1426.     blitter per la seconda
  1427.     blittata
  1428.  
  1429. 5)    attendi la fine
  1430.     della seconda blittata
  1431.  
  1432. 6)    carica i registri del
  1433.     blitter per la terza
  1434.     blittata
  1435.  
  1436.  
  1437. Come vedete, nel caso di schermo interleaved, il processore deve fare meno
  1438. operazioni, e sopratutto deve attendere una sola volta che il blitter finisca,
  1439. mentre nel caso di schermo normale deve attendere un numero di volte pari
  1440. al numero dei bitplanes. Poiche` durante un attesa il processore non fa nulla
  1441. di utile e non ha bisogno di riposo, e` opportuno farlo lavorare il piu`
  1442. possibile diminuendo il numero di attese.
  1443.  
  1444. L'esempio lezione9g2.s e` la versione INTERLEAVED dell'esempio lezione9f1.s.
  1445. Guardateli insieme, notando le differenze che essi presentano.
  1446.  
  1447. L'esempio lezione9g3.s, invece, e` la versione INTERLEAVED dell'esempio
  1448. lezione9f3.s. Confrontate anche questi.
  1449.                                    ........
  1450.                                .::::::::::::::.
  1451.                               ::::::::::::::::::
  1452.                              :::       :::::::::.
  1453.                             :::          ::::::::
  1454.                            ::(__   ___    ::::::::
  1455.                            .::/_)  /__,  :/_\::::.
  1456.                           .:::o/    o   .: //::::::
  1457.                            .::/        .::./::::::
  1458.                            ::(__  )   .::  ::::::
  1459.                            .::/()    .::   ::::::'
  1460.      _n_____________n__                      (___           ::::
  1461.     |-----------\\\--__F                       \ ~           |
  1462.     |_____________ (O_.\________      __________\___.      ./X\
  1463.              \(__D)__\   \\     ~~~~~~             \______/.xST\
  1464.               `-(___O)|_  ||        .                         XX|
  1465.                 (___O) \_//          :          .:    .        ×|
  1466.                   (__O)///__________ //________.:     :        .|
  1467.                                     ~~~        :      :         :
  1468.                                                .      .         .
  1469.  
  1470. *******************************************************************************
  1471. *                MASCHERE                      *
  1472. *******************************************************************************
  1473.  
  1474. Il blitter ha la possibilita' di mascherare la prima e l'ultima word di ogni
  1475. riga che passa attraverso il canale A. Mascherare vuol dire leggere solo
  1476. alcuni bit di tali word e ignorare gli altri. Questa operazione viene
  1477. effettuata grazie a due registri, che finora avevamo usato senza spiegarne il
  1478. significato. Questi due registri sono chiamati BLTAFWM ($dff044) e BLTALWM
  1479. ($dff046), e servono rispettivamente per mascherare la prima e l'ultima word
  1480. di ogni riga letta attraverso il canale A. Ogniuno di essi contiene una word,
  1481. detta maschera. Il blitter quando legge la prima o l'ultima word di una riga
  1482. esegue un'operazioine logica di AND tra la word letta e la maschera
  1483. corrispondente. I bit della word letta dal canale A in corrispondenza dei
  1484. quali c'e` un bit settato a 0 nella maschera verranno cancellati.
  1485. Vediamo qualche esempio:
  1486.  
  1487. word letta dal
  1488. canale A    %1001101100010111
  1489.  
  1490. maschera    %1111111100000000
  1491. _________________________________
  1492.  
  1493. risultato    %1001101100000000
  1494.  
  1495. in questo modo abbiamo selezionato solo gli 8 bit piu` a destra della word.
  1496.  
  1497. word letta dal
  1498. canale A    %1001101100010111
  1499.  
  1500. maschera    %1111110000111111
  1501. _________________________________
  1502.  
  1503. risultato    %1001100000010111
  1504.  
  1505. in questo modo abbiamo azzerato i 4 bit al centro della maschera.
  1506. Se azzeriamo completamente la maschera, cancelliamo tutta la word:
  1507.  
  1508. word letta dal
  1509. canale A    %1001101100010111
  1510.  
  1511. maschera    %0000000000000000
  1512. _________________________________
  1513.  
  1514. risultato    %0000000000000000
  1515.  
  1516. Se invece poniamo la maschera al valore $ffff=%1111111111111111=-1 la maschera
  1517. non cancella nulla, ovvero "fa passare" tutta la word:
  1518.  
  1519. word letta dal
  1520. canale A    %1001101100010111
  1521.  
  1522. maschera    %1111111111111111
  1523. _________________________________
  1524.  
  1525. risultato    %1001101100010111
  1526.  
  1527. In tutti gli esempi che abbiamo visto finora non abbiamo avuto bisogno di
  1528. mascherare nulla e infatti abbiamo inizializzato entrambe le maschere al
  1529. valore $ffff.
  1530.  
  1531. La prima word di ogni riga (cioe` la word piu` a sinistra) è "ANDizzata" con
  1532. BLTAFWM, e l'ultima word (la word piu` a destra) è "ANDizzata" con BLTALWM.
  1533. Potete facilmente ricordarlo perche` la F nel nome BLTAFWM indica "First"
  1534. che come tutti sanno significa "prima" e la L in BLTALWM indica "Last",
  1535. cioe` ultima. Naturalmente le 2 maschere possono essere diverse tra loro
  1536. (senno` a che ci servirebbero 2 registri?). Se la larghezza della riga è una
  1537. singola word, entrambe le maschere vengono applicate simultaneamente alla
  1538. stessa word. Poiche` i 2 registri BLTAFWM e BLTALWM hanno indirizzi consecutivi
  1539. e` possibile inizializzarli con una sola istruzione MOVE.L #maschera,$dff044.
  1540. E` importante notare che le maschere vengono applicate ai dati PRIMA di 
  1541. eseguire lo SHIFT. I canali B e C non hanno invece la possibilita` di
  1542. mascherare le words lette.
  1543.  
  1544. Nell'esempio lezione9h1.s mostriamo l'effetto delle maschere con semplici
  1545. operazioni di copia.
  1546.  
  1547. In lezione9h2.s abbiamo una dimostrazione dell'utilita` delle maschere
  1548. nell'"estrarre" da un'immagine solo la parte che ci interessa.
  1549.  
  1550. In lezione9h3.s e lezione9h4.s presentiamo 2 nuovi effetti realizzati con
  1551. l'ausilio delle maschere.
  1552.  
  1553. Gli esempi lezione9h2r.s, lezione9h3r.s e lezione9h4r.s sono le versioni in
  1554. formato rawblit (interleaved) di lezione9h1.s lezione9h2.s e lezione9h3.s.
  1555. Fate un confronto incrociato, notando tutte le differenze che ci sono
  1556. (in particolare notate che tutte le routines in versione interleaved non hanno
  1557. la necessita` di fare un loop per blittare su ogni plane, e pertanto hanno una
  1558. struttura molto piu` semplice).
  1559.  
  1560. Dopo aver visto i nuovi effetti, torniamo ad occuparci di uno vecchio, cioe`
  1561. del pesce che nuota sullo schermo, per scoprire che, con le nostre nuove
  1562. conoscenze sul blitter, possiamo realizzare un'importante miglioria. 
  1563. Abbiamo visto, infatti che per shiftare correttamente una figura, e` necessario
  1564. aggiungere a destra della figura una "colonna" di word azzerate. Questo fatto
  1565. ci costringe a sprecare piu` memoria del necessario per memorizzare le figure.
  1566. Ma ora, grazie alle maschere, possiamo evitare questo spreco.
  1567. Per shiftare e` necessario che l'ultima word di ogni riga della figura sia
  1568. azzerata.
  1569. Invece di leggere direttamente dalla memoria una word azzerata, possiamo
  1570. leggere una word di qualsiasi valore e azzerarla tramite le maschera.
  1571. Siccome il mascheramento viene effettuato PRIMA dello shift, al circuito di
  1572. shift arrivera` comunque l'ultima word di ogni riga azzerata, e tutto si
  1573. svolgera` come se la word azzerata fosse stata letta dalla memoria.
  1574. Visto che non ha importanza il valore dell'ultima word della riga, possiamo
  1575. leggere una word di qualsiasi valore.
  1576.  
  1577. Proviamo allora a fare il seguente giochino: non aggiungiamo nessuna word a
  1578. destra dell'immagine, ma senza dirlo al blitter, cioe` settiamo la larghezza
  1579. della blittata come se ci fosse una word in piu` a destra della figura. 
  1580. Il blitter, quindi, dopo aver letto l'ultima word di una riga, pensera` di
  1581. dover leggere ancora una word, e pertanto leggera` la word successiva a
  1582. l'ultima della riga. Che cos'e` questa word? Se usiamo un immagine in formato
  1583. normale, sara` la prima word della riga successiva dello stesso bitplane,
  1584. mentre se l'immagine e` in formato interleaved sara` la prima word di una
  1585. riga di un altro bitplane. In ogni caso sara` comunque una word non nulla, ma
  1586. per noi non c'e` problema perche` la possiamo azzerare con la maschera.
  1587. A questo punto abbiamo solo un problemino: siccome abbiamo letto una word di
  1588. troppo, il puntatore della sorgente si e` spostato in avanti di una word,
  1589. pertanto quando iniziera` a leggere la prossima riga partira` dalla seconda
  1590. word invece che dalla prima. Come si puo` far tornare indietro il puntatore?
  1591. Naturalmente con il vecchio trucco del modulo negativo! Settando il modulo
  1592. della sorgente a -2 (il modulo si esprime in bytes) il blitter si riposiziona
  1593. sulla prima word della riga seguente. Riassumiamo tutto tornando all'esempio
  1594. del pesce che abbiamo usato per illustrare lo shift. Abbiamo dunque un'immagine
  1595. di un solo bitplane, larga 1 word e alta 6 righe. Come abbiamo detto, NON
  1596. aggiungiamo la colonna di word sulla destra.
  1597.  
  1598. SORGENTE
  1599.         word 1        
  1600. riga 1        1000001111100000
  1601.   "  2        1100111111111000
  1602.   "  3        1111111111101100
  1603.   "  4        1111111111111110
  1604.   "  5        1100111111111000
  1605.   "  6        1000001111100000
  1606.                 
  1607.         Fig. 17 NON aggiungiamo nessuna colonna di words
  1608.  
  1609. Tuttavia, facciamo finta che la colonna in piu` ci sia, e quindi blittiamo
  1610. un rettangolo largo 2 words e alto 6 righe. Il blitter legge quindi 2 words
  1611. per ogni riga, prendendo come seconda word la prima word della riga successiva.
  1612. Vediamo in particolare, con l'aiuto della figura seguente, cosa accade durante
  1613. la lettura della prima riga:
  1614.  
  1615. SORGENTE
  1616.         word 1        
  1617. riga 1        1000001111100000--------
  1618.   "  2        1100111111111000--------+-----------------------
  1619.   "  3        1111111111101100    |            |
  1620.   "  4        1111111111111110    |            |
  1621.   "  5        1100111111111000    |            |
  1622.   "  6        1000001111100000    |            |
  1623.                     |            |
  1624.                     V            V
  1625. WORDS LETTE                
  1626. DAL CANALE A            1000001111100000    1100111111111000
  1627.                     |            |
  1628.                     |            |
  1629.                     V            V
  1630. L'ULTIMA WORD DELLA
  1631. RIGA VIENE MASCHERATA        1000001111100000    0000000000000000
  1632.                     |            |
  1633.                     |            |
  1634.                     V            V
  1635.  
  1636. SHIFT (2 pixel)            0010000011111000    0000000000000000
  1637.                     |            |
  1638.                     |            |
  1639.                     V            V
  1640.  
  1641.                 Scritta al canale D    Scritta al canale D
  1642.  
  1643.         Fig. 18     Shift con azzeramento dell'ultima word.
  1644.  
  1645.  
  1646. Come vedete la seconda word letta viene azzerata prima di essere shiftata.
  1647. Dopo lo shift le 2 word vengono scritte attraverso il canale D.
  1648. Nel frattempo il puntatore al canale A si e` spostato in avanti di 2 words,
  1649. e punta cioe` alla prima word della terza riga. Noi invece dobbiamo farlo
  1650. puntare alla prima word della seconda riga, cioe` dobbiamo farlo tornare
  1651. indietro di una word. Usiamo quindi un modulo pari a -2. Gli spostamenti
  1652. del puntatore sono illustrati dalla figura seguente:
  1653.  
  1654.     SORGENTE        WORD PUNTATA    WORD PUNTATA    WORD PUNTATA
  1655.                 ALL'INIZIO    DOPO LA PRIMA    AGGIUNGENDO
  1656.                      |        RIGA        IL MODULO
  1657.     1000001111100000    <----            |           |
  1658.     1100111111111000    <-------------------+--------------
  1659.     1111111111101100    <-------------------
  1660.     1111111111111110
  1661.     1100111111111000
  1662.     1000001111100000
  1663.  
  1664.         Fig. 19     Movimento del puntatore alla sorgente.
  1665.  
  1666. Per vedere il nostro pesce in azione consultate l'esempio lezione9i1.s.
  1667.  
  1668. Ormai sappiamo muovere molto bene delle figure sullo schermo usando il blitter.
  1669. Queste figure vengono chiamate BOB che e` un abbreviazione del termine
  1670. inglese "Blitter OBject", ovvero oggetti creati dal blitter.
  1671. Con i BOB Possiamo fare le stesse cose che sappiamo fare con gli sprites
  1672. hardware. I BOB sono piu` lenti degli sprites, perche` il blitter impiega
  1673. comunque un certo tempo per copiare dati. Per contro, pero` i BOBS non soffrono
  1674. delle limitazioni degli sprites riguardo a dimensione, colori e numero massimo.
  1675. Infatti un BOB puo` essere grande quanto vogliamo noi (e` ovvio pero` che al
  1676. crescere delle dimensioni cresce la quantita` di memoria occupata, e di
  1677. conseguenza il tempo necesario al blitter per spostarlo), e puo` avere
  1678. un numero di colori pari a quello dello schermo.
  1679. Inoltre non c'e` nessun limite per quanto rigurda il numero di bob
  1680. contemporaneamente sullo schermo (ovviamente pero`, piu` bob ci sono, piu`
  1681. tempo perdiamo per disegnarli).
  1682. "Che bello", direte voi, "possiamo iniziare a fare un gioco!". Un attimo, non
  1683. esaltiamoci troppo. Siamo proprio sicuri di saper fare con i BOB le stesse cose
  1684. che possimo fare con gli sprites?
  1685.  
  1686. Guardiamo lezione9i2.s e il suo "gemello" in formato interleaved lezione9i2r.s.
  1687.  
  1688. Abbiamo un BOB colorato che spostiamo liberamente con il mouse sullo schermo.
  1689. Pero` c'e` un problema... muovendo il BOB cancelliamo lo sfondo!
  1690. Questo con gli sprite non accade, in quanto gli sprite sono dei piccoli
  1691. bitplanes separati dai bitplanes dello sfondo.
  1692. I BOB invece vengono disegnati proprio sui bitplane dell'immagine di sfondo,
  1693. quindi in parte la sovrascrivono.
  1694.  
  1695. Una prima soluzione al problema la presentiamo negli esempi lezione9i3.s e
  1696. lezione9i3r.s (naturalmente il secondo e` la versione rawblit del primo).
  1697.  
  1698. Come vedrete, pero` non e` ancora soddisfacente.
  1699.  
  1700. Nell'esempio lezione9i4.s proviamo un'altra soluzione, ma anch'essa presenta
  1701. problemi.
  1702.  
  1703. Nell'esempio lezione9i5.s, invece vediamo un esempio di bob mosso dal joystick
  1704. che esce parzialmente dallo schermo.
  1705.  
  1706. Abbiamo iniziato a conoscere i BOB, ma per ora non abbiamo raggiunto un
  1707. risultato soddisfacente, cioe` riuscire a fare con i BOB le operazioni tipiche
  1708. videogiochi a causa del problema dello sfondo. Purtroppo con quello che
  1709. sappiamo finora non si puo` fare di meglio.
  1710.  
  1711. Ma non preoccupatevi: ci sono ancora molte cose da imparare sul blitter, e
  1712. una di queste ci aiutera` a risolvere il problema!
  1713. Forza e coraggio dunque, la strada e` ancora lunga!
  1714.              .
  1715.               )                       \\\..
  1716.             (                       __/ __ \
  1717.              )                      (.__.)  O
  1718.             (  n_______n            /(__,    \
  1719.               |________ }__________/ ____,    )__
  1720.                    ((O) \\.       (__________/   \
  1721.                     =(_O) |          /(    )\     \
  1722.                       (_O)|_______   \_\  /_/  \   )
  1723.                                   \    \)(/     | /
  1724.                                    )   /. \     |/
  1725.                                    |  / .  \    |
  1726.                                    | (__.___)   |
  1727.                                    |_|==()==|___|
  1728.                                     |   _      |
  1729.                                     |   |      |
  1730.                                     |   |      |
  1731.  
  1732. *******************************************************************************
  1733. *        COPIA DI ZONE DI MEMORIA SOVRAPPOSTE                  *
  1734. *******************************************************************************
  1735.  
  1736. Illustreremo ora un'altra caratteristica del blitter prendendo spunto dalla
  1737. copia di rettangoli, operazione che ormai conosciamo bene. Cosa succede se
  1738. la sorgente e la destinazione della blittata sono sovrapposte, ovvero sono
  1739. 2 rettangoli di word che hanno delle parti in comune? E` ovvio che la blittata
  1740. modifichera` tutta la destinazione, comprese quindi le parti in comune con la
  1741. sorgente.
  1742. La copia tra zone sovrapposte consiste quindi nel mettere il contenuto della
  1743. sorgente PRIMA della copia nella destinazione.
  1744. Dopo la copia, il contenuto della sorgente sara` cambiato.
  1745. Pertanto, dopo la copia, la destinazione NON sara` uguale alla sorgente!!
  1746. Piuttosto, ripetiamo, essa sara` uguale a come era la sorgente PRIMA della
  1747. copia!
  1748. Insomma immaginate che la destinazione sia una fotografia scattata alla
  1749. sorgente, e che durante il tempo impiegato dal fotografo per sviluppare la
  1750. foto, la sorgente sia invecchiata rapidamente tanto da apparire molto diversa
  1751. da come appare nella foto.
  1752. E` sempre effettuare una copia in tali condizioni?
  1753. Dobbiamo studiare bene il problema.
  1754. Vediamo cosa succede con un esempio di una copia di un rettangolo alto 2
  1755. righe e largo 3 words.
  1756. Supponiamo che la sorgente si trovi piu` in basso della destinazione, come
  1757. illustrato dalla figura seguente:
  1758.  
  1759.          ____ ____ ____ ____ ____ ____
  1760.         |    |\\\\|\\\\|\\\\|    |    |
  1761.         |    |\\\\|\\\\|\\\\|    |    |
  1762.         |____|\\\\|\\\\|\\\\|____|____|        rett. SORGENTE=////
  1763.         |    |\\\\|XXXX|XXXX|////|    |
  1764.         |    |\\\\|XXXX|XXXX|////|    |        rett. DESTINAZIONE=\\\\
  1765.         |____|\\\\|XXXX|XXXX|////|____|
  1766.         |    |    |////|////|////|    |        rett. IN COMUNE=XXXX
  1767.         |    |    |////|////|////|    |
  1768.         |____|____|////|////|////|____|
  1769.         |    |    |    |    |    |    |
  1770.         |    |    |    |    |    |    |
  1771.         |____|____|____|____|____|____|
  1772.  
  1773.  
  1774.         Fig. 20     Blittata tra rettangoli sovrapposti
  1775.  
  1776. Analizziamo, con l'aiuto di una serie di figure, le successive fasi
  1777. dell'operazione. Indichiamo con le lettere A,B,C,D,E,F il contenuto delle 6
  1778. words che vogliamo copiare, e con il simbolo "?" il contenuto delle word che
  1779. non ci interessano, e che quindi possiamo anche cancellare.
  1780. Prima di iniziare la copia, abbiamo questa situazione:
  1781.  
  1782.          ____ ____ ____ ____ ____ ____
  1783.         |    |\\\\|\\\\|\\\\|    |    |
  1784.         |    |  ? |  ? |  ? |    |    |
  1785.         |____|\\\\|\\\\|\\\\|____|____|        rett. SORGENTE=////
  1786.         |    |\\\\|XXXX|XXXX|////|    |
  1787.         |    |  ? |  A |  B |  C |    |        rett. DESTINAZIONE=\\\\
  1788.         |____|\\\\|XXXX|XXXX|////|____|
  1789.         |    |    |////|////|////|    |        rett. IN COMUNE=XXXX
  1790.         |    |    |  D |  E |  F |    |
  1791.         |____|____|////|////|////|____|
  1792.  
  1793.  
  1794.         Fig. 21a Blittata tra rettangoli sovrapposti
  1795.  
  1796. Come sappiamo il blitter copia le words una alla volta partendo da quella piu`
  1797. in alto a sinistra e proseguendo verso il basso e verso destra. La prima riga
  1798. viene letta e copiata su una zona della destinazione non in comune, e che
  1799. quindi possiamo sovrascrivere tranquillamente. Ecco la situazione dopo la copia
  1800. della prima riga:
  1801.  
  1802.          ____ ____ ____ ____ ____ ____
  1803.         |    |\\\\|\\\\|\\\\|    |    |
  1804.         |    |  A |  B |  C |    |    |
  1805.         |____|\\\\|\\\\|\\\\|____|____|        rett. SORGENTE=////
  1806.         |    |\\\\|XXXX|XXXX|////|    |
  1807.         |    |  ? |  A |  B |  C |    |        rett. DESTINAZIONE=\\\\
  1808.         |____|\\\\|XXXX|XXXX|////|____|
  1809.         |    |    |////|////|////|    |        rett. IN COMUNE=XXXX
  1810.         |    |    |  D |  E |  F |    |
  1811.         |____|____|////|////|////|____|
  1812.  
  1813.  
  1814.         Fig. 21b Blittata tra rettangoli sovrapposti
  1815.  
  1816. A questo punto dobbiamo copiare la seconda riga. La seconda riga della
  1817. destinazione si sovrappone con la prima riga della sorgente. Questo significa
  1818. che quando scriveremo i dati nella destinazione, sovrascriveremo una parte
  1819. della sorgente, distruggendone il contenuto. Osservate pero` che i dati
  1820. sovrascritti appartengono alla PRIMA riga della sorgente, che noi abbiamo gia`
  1821. copiato, e che quindi non ci serve piu`. Pertanto non ci sono problemi.
  1822. La situazione dopo la copia della seconda (e ultima) riga e` la seguente:
  1823.  
  1824.          ____ ____ ____ ____ ____ ____
  1825.         |    |\\\\|\\\\|\\\\|    |    |
  1826.         |    |  A |  B |  C |    |    |
  1827.         |____|\\\\|\\\\|\\\\|____|____|        rett. SORGENTE=////
  1828.         |    |\\\\|XXXX|XXXX|////|    |
  1829.         |    |  D |  E |  F |  C |    |        rett. DESTINAZIONE=\\\\
  1830.         |____|\\\\|XXXX|XXXX|////|____|
  1831.         |    |    |////|////|////|    |        rett. IN COMUNE=XXXX
  1832.         |    |    |  D |  E |  F |    |
  1833.         |____|____|////|////|////|____|
  1834.  
  1835.  
  1836.         Fig. 21c Blittata tra rettangoli sovrapposti
  1837.  
  1838. Abbiamo ottenuto proprio cio` che volevamo, in quanto ora il rettangolo
  1839. destinazione e` la copia esatta del contenuto del rettangolo sorgente PRIMA
  1840. che iniziassimo la blittata. Notate che ora, invece il contenuto della sorgente
  1841. e` cambiato, ma cio` era inevitabile.
  1842.  
  1843. Potete vedere tutto cio` in pratica nell'esempio lezione9l1.s.
  1844.  
  1845. Sembrerebbe dunque che la sovrapposizione tra sorgente e destinazione non crei
  1846. problemi. Proviamo pero` ad esaminare il caso in cui la destinazione si trovi
  1847. piu` in basso della sorgente:
  1848.  
  1849.          ____ ____ ____ ____ ____ ____
  1850.         |    |////|////|////|    |    |
  1851.         |    |////|////|////|    |    |
  1852.         |____|////|////|////|____|____|        rett. SORGENTE=////
  1853.         |    |////|XXXX|XXXX|\\\\|    |
  1854.         |    |////|XXXX|XXXX|\\\\|    |        rett. DESTINAZIONE=\\\\
  1855.         |____|////|XXXX|XXXX|\\\\|____|
  1856.         |    |    |\\\\|\\\\|\\\\|    |        rett. IN COMUNE=XXXX
  1857.         |    |    |\\\\|\\\\|\\\\|    |
  1858.         |____|____|\\\\|\\\\|\\\\|____|
  1859.         |    |    |    |    |    |    |
  1860.         |    |    |    |    |    |    |
  1861.         |____|____|____|____|____|____|
  1862.  
  1863.  
  1864.         Fig. 22     Blittata tra rettangoli sovrapposti
  1865.  
  1866. Prima della blittata, la situazione e` la seguente:
  1867.  
  1868.          ____ ____ ____ ____ ____ ____
  1869.         |    |////|////|////|    |    |
  1870.         |    |  A |  B |  C |    |    |
  1871.         |____|////|////|////|____|____|        rett. SORGENTE=////
  1872.         |    |////|XXXX|XXXX|\\\\|    |
  1873.         |    |  D |  E |  F |  ? |    |        rett. DESTINAZIONE=\\\\
  1874.         |____|////|XXXX|XXXX|\\\\|____|
  1875.         |    |    |\\\\|\\\\|\\\\|    |        rett. IN COMUNE=XXXX
  1876.         |    |    |  ? |  ? |  ? |    |
  1877.         |____|____|\\\\|\\\\|\\\\|____|
  1878.  
  1879.         Fig. 23a Blittata tra rettangoli sovrapposti
  1880.  
  1881. Iniziamo con il copiare la prima riga. La prima riga della destinazione e`
  1882. parzialmente sovrapposta con la seconda riga della sorgente, che non e`
  1883. ancora stata copiata. Ecco quello che si ottiene:
  1884.  
  1885.          ____ ____ ____ ____ ____ ____
  1886.         |    |////|////|////|    |    |
  1887.         |    |  A |  B |  C |    |    |
  1888.         |____|////|////|////|____|____|        rett. SORGENTE=////
  1889.         |    |////|XXXX|XXXX|\\\\|    |
  1890.         |    |  D |  A |  B |  C |    |        rett. DESTINAZIONE=\\\\
  1891.         |____|////|XXXX|XXXX|\\\\|____|
  1892.         |    |    |\\\\|\\\\|\\\\|    |        rett. IN COMUNE=XXXX
  1893.         |    |    |  ? |  ? |  ? |    |
  1894.         |____|____|\\\\|\\\\|\\\\|____|
  1895.  
  1896.         Fig. 23b Blittata tra rettangoli sovrapposti
  1897.  
  1898. Come potete notare ci siamo persi i valori E ed F! Sembra proprio che stavolta
  1899. la copia non riuscira` bene! Comunque copiamo anche la seconda riga, e vediamo
  1900. che succede.
  1901.  
  1902.          ____ ____ ____ ____ ____ ____
  1903.         |    |////|////|////|    |    |
  1904.         |    |  A |  B |  C |    |    |
  1905.         |____|////|////|////|____|____|        rett. SORGENTE=////
  1906.         |    |////|XXXX|XXXX|\\\\|    |
  1907.         |    |  D |  A |  B |  C |    |        rett. DESTINAZIONE=\\\\
  1908.         |____|////|XXXX|XXXX|\\\\|____|
  1909.         |    |    |\\\\|\\\\|\\\\|    |        rett. IN COMUNE=XXXX
  1910.         |    |    |  D |  A |  B |    |
  1911.         |____|____|\\\\|\\\\|\\\\|____|
  1912.  
  1913.  
  1914.         Fig. 23c Blittata tra rettangoli sovrapposti
  1915.  
  1916. Ecco fatto. La blittata e` finita ma il risultato non e` quello che volevamo.
  1917. Siete convinti?
  1918.  
  1919. No? Allora, guardatevi l'esempio lezione9l2.s e convincetevene!
  1920.  
  1921. Cerchiamo di capire perche` la prima volta ha funzionato e stavolta no.
  1922. Il problema nasce quando scriviamo sulle parti della destinazione che si
  1923. sovrappongono con la sorgente, perche` cosi` facendo sovrascriviamo alcuni
  1924. dati.
  1925. Nel primo caso non ci sono stati problemi perche` i dati sovrascritti li
  1926. avevamo gia` copiati.
  1927. Cio` e` accaduto perche` la sorgente si trova piu` in basso (ad indirizzi
  1928. maggiori) della destinazione, e la sovrapposizione si verifica tra la prima
  1929. riga della sorgente e la seconda riga della destinazione.
  1930. Siccome il blitter copia partendo dalla prima riga, i dati della prima riga
  1931. della sorgente vengono copiati PRIMA di essere sovrascritti dalla seconda riga
  1932. della destinazione.
  1933. Nel secondo caso, invece, la sorgente si trova piu` in alto (ad indirizzi
  1934. minori) della destinazione, e la sovrapposizione si verifica tra la seconda
  1935. riga della sorgente e la prima della destinazione.
  1936. I dati della seconda riga della sorgente, quindi, vengono sovrascritti durante
  1937. la copia della prima riga, e cioe` PRIMA di essere copiati a loro volta,
  1938. pertanto vengono persi.
  1939. Per risolvere questo problema, bisognerebbe copiare prima la seconda riga e
  1940. poi la prima.
  1941. Cio` e` possibile utilizzando il MODO DISCENDENTE del blitter.
  1942. Quando si utilizza questo modo, il blitter esegue la copia (o una qualunque
  1943. altra operazione) in senso inverso a quanto fa di solito, cioe` parte dalla
  1944. word piu` in basso a destra del rettangolo e prosegue verso sinistra e verso
  1945. l'alto.
  1946. Le words che blitta seguendo questo percorso hanno indirizzo via via minore.
  1947. Si dice percio` che il blitter DISCENDE lungo la memoria, da cui il nome del
  1948. modo di funzionamento (per contrasto, il modo normale viene detto anche MODO
  1949. ASCENDENTE, infatti normalmente vengono blittate words con indirizzi via via
  1950. crescenti).
  1951. Prima di esaminare nel dettaglio come si usa il blitter in modo discendente,
  1952. ritorniamo al problema della copia di regioni sovrapposte e verifichiamo che 
  1953. il modo discendente e` la giusta soluzione.
  1954. La situazione di partenza e` la seguente:
  1955.  
  1956.          ____ ____ ____ ____ ____ ____
  1957.         |    |////|////|////|    |    |
  1958.         |    |  A |  B |  C |    |    |
  1959.         |____|////|////|////|____|____|        rett. SORGENTE=////
  1960.         |    |////|XXXX|XXXX|\\\\|    |
  1961.         |    |  D |  E |  F |  ? |    |        rett. DESTINAZIONE=\\\\
  1962.         |____|////|XXXX|XXXX|\\\\|____|
  1963.         |    |    |\\\\|\\\\|\\\\|    |        rett. IN COMUNE=XXXX
  1964.         |    |    |  ? |  ? |  ? |    |
  1965.         |____|____|\\\\|\\\\|\\\\|____|
  1966.  
  1967.         Fig. 24a Blittata tra rettangoli sovrapposti
  1968.  
  1969. Questa volta usiamo il modo discendente, percio` iniziamo a copiare a partire
  1970. dall'ultima riga. In questo modo all'inizio non scriviamo sulla parte
  1971. sovrapposta:
  1972.  
  1973.          ____ ____ ____ ____ ____ ____
  1974.         |    |////|////|////|    |    |
  1975.         |    |  A |  B |  C |    |    |
  1976.         |____|////|////|////|____|____|        rett. SORGENTE=////
  1977.         |    |////|XXXX|XXXX|\\\\|    |
  1978.         |    |  D |  E |  F |  ? |    |        rett. DESTINAZIONE=\\\\
  1979.         |____|////|XXXX|XXXX|\\\\|____|
  1980.         |    |    |\\\\|\\\\|\\\\|    |        rett. IN COMUNE=XXXX
  1981.         |    |    |  D |  E |  F |    |
  1982.         |____|____|\\\\|\\\\|\\\\|____|
  1983.  
  1984.         Fig. 24b Blittata tra rettangoli sovrapposti
  1985.  
  1986. Adesso copiamo la prima riga. Nel farlo sovrascriviamo la seconda riga della
  1987. sorgente, ma poiche` l'abbiamo gia` copiata non e` un problema:
  1988.  
  1989.          ____ ____ ____ ____ ____ ____
  1990.         |    |////|////|////|    |    |
  1991.         |    |  A |  B |  C |    |    |
  1992.         |____|////|////|////|____|____|        rett. SORGENTE=////
  1993.         |    |////|XXXX|XXXX|\\\\|    |
  1994.         |    |  D |  A |  B |  C |    |        rett. DESTINAZIONE=\\\\
  1995.         |____|////|XXXX|XXXX|\\\\|____|
  1996.         |    |    |\\\\|\\\\|\\\\|    |        rett. IN COMUNE=XXXX
  1997.         |    |    |  D |  E |  F |    |
  1998.         |____|____|\\\\|\\\\|\\\\|____|
  1999.  
  2000.         Fig. 24c Blittata tra rettangoli sovrapposti
  2001.  
  2002. OK! Questa volta ci siamo. Ora la destinazione ha lo stesso aspetto della
  2003. sorgente prima di effettuare la blittata.
  2004. Per concludere, possiamo quindi dire che quando effettuiamo una copia con
  2005. sorgente e destinazione sovrapposte, se la sorgente si trova ad indirizzi
  2006. di memoria maggiori della destinazione, si deve fare la blittata in modo
  2007. normale (ASCENDENTE), se invece la sorgente si trova ad indirizzi di memoria
  2008. minori, si deve utilizzare il modo DISCENDENTE.
  2009.                        __________
  2010.                       /          \
  2011.                      |_________ _ |
  2012.                      / _______ \| |
  2013.                     | /  o_o  \ | |
  2014.                      \|  ___  |/\_|
  2015.                  _____|\/ = \/|_(_)__
  2016.                 /     |       |      \
  2017.                /      |       |       \
  2018.               /  _.    \_____/    __  _\_____
  2019.           ___/__ |        o        | _\_     \____
  2020.          /   \_ \|        o        |/ __\__|     /
  2021.         |     |) |\_______________/|\(__/  \_/__/__
  2022.         O==o==O_/|     ||__||      | / ____        \_
  2023.         | `-' |   \____||__||_____/ /   / _    ___   \
  2024.         | sk8 |    \             / (   / (_)\/ \      |
  2025.         | .-. |     |_____Y_____|   \       / \/     /
  2026.         O==o==O   __|     |    _|_   |           '   )
  2027.         |     |  / ``     |    '' \  (              /
  2028.          \___/  (_________|________)  \_____________)
  2029.  
  2030. A questo punto possiamo scendere nel dettaglio del modo discendente.
  2031. Innanzitutto, il modo discendente va attivato mediante un bit di controllo.
  2032. Si tratta del bit 1 del registro BLTCON1, che se settato ad 1 attiva il modo
  2033. discendente, mentre quando viene azzerato (come abbiamo fatto finora)
  2034. attiva il modo ascendente.
  2035. Come abbiamo gia` detto, in modo discendente il blitter va "all'indietro"
  2036. cioe` si sposta tra locazioni di memoria di indirizzo via via minore.
  2037. Per questo e` necessario che i puntatori dei canali DMA puntino all'inizio
  2038. della blittata alla word della blittata che ha indirizzo maggiore di tutte,
  2039. cioe` la prima word che verra` blittata.
  2040. Si tratta, come sapete, della word piu` in basso e piu` a destra del
  2041. rettangolo di words che verra` blittato.
  2042. Per esempio, nel caso in cui si voglia blittare un rettangolo largo 3 words e
  2043. alto 2 righe, si dovranno inizializzare i puntatori con l'indirizzo della terza
  2044. word della seconda riga del rettangolo, che nella figura e` indicata con due
  2045. asterischi (**)
  2046.  
  2047.          ____ ____ ____ ____ _ _ _ _ _ _ ____
  2048.         |    |    |    |    |        |    |
  2049.         |    |    |    |    |            |    |
  2050.         |____|____|____|____|        |____|
  2051.         |    |\\\\|\\\\|\\\\|        |    |
  2052.         |    |\\\\|\\\\|\\\\|        |    |
  2053.         |____|\\\\|\\\\|\\\\|        |____|
  2054.         |    |\\\\|\\\\|\\\\|        |    |
  2055.         |    |\\\\|\\\\| ** |        |    |
  2056.         |____|\\\\|\\\\|\\\\|        |____|
  2057.         |    |    |    |    |        |    |
  2058.         |    |    |    |    |            |    |
  2059.         |____|____|____|____|        |____|
  2060.         |                     |
  2061.         |                     |
  2062.  
  2063.         Fig. 25 Rettangolo di word con evidenziata la word
  2064.             da puntare all'inizio della blittata
  2065.  
  2066. Per calcolare l'indirizzo di tale word si segue un ragionamento simile a quello
  2067. fatto nel caso ascendente. Dobbiamo calcolare la distanza (offset) di tale word
  2068. dall'inizio del bitplane. Supponiamo di conoscere le coordinate Xa e Ya del
  2069. pixel piu` in alto a sinistra del rettangolo, ed anche la larghezza in words L
  2070. e l'altezza A del rettangolo. La word che ci interessa appartiene all'ultima
  2071. riga del rettangolo che ha coordinata Yb=Ya+A. L'offset della prima word di
  2072. tale riga e` dato dalla seguente formula:
  2073.  
  2074. OFFSET_Y = 2*(Yb*NUMERO_WORDS_PER_RIGA)            nel caso normale e
  2075.  
  2076. OFFSET_Y = 2*(Yb*NUMERO_WORDS_PER_RIGA*NUMERO_PLANES)    nel caso interleaved.
  2077.  
  2078. Ora dobbiamo calcolare la distanza tra la prima word della riga e l'ultima word
  2079. del rettangolo. Come sappiamo tale distanza e` data da 2*(Xa/16).
  2080. D'altronde tra la prima e l'ultima word del rettangolo ci sono L-1 words, che
  2081. equivalgono ad una distanza (che si esprime in bytes) di 2*(L-1).
  2082. Sommando le 2 differenze abbiamo:
  2083.  
  2084. OFFSET_X=2*(Xa/16+L-1).
  2085.  
  2086.  
  2087.     |    |        |    |\\\\|\\\\|    |\\\\|
  2088.     |  A |        |    |  B |\\\\|    |  C |
  2089.     |____|_ _    |____|\\\\|\\\\|_ _    |\\\\|
  2090.  
  2091.     \____________________/\______________________/
  2092.         |            |
  2093.         Xa/16 words           L words
  2094.  
  2095.     distanza tra word A e word B = 2*(Xa/16)
  2096.     distanza tra word B e word C = 2*(L-1)
  2097.  
  2098.         Fig. 26 Calcolo OFFSET_X
  2099.  
  2100. Quindi l'indirizzo da scrivere nei puntatori dei canli DMA e` dato da:
  2101.  
  2102. INDIRIZZO_WORD = INDIRIZZO_BITPLANE+OFFSET_Y+OFFSET_X.
  2103.  
  2104. Per quanto riguarda i moduli e la dimensione della blittata, non ci sono
  2105. differenze rispetto al caso ascendente, vengono calcolati tutti con le stesse
  2106. formule. Ora possiamo finalmente copiare correttamente 2 regioni rettangolari
  2107. sovrapposte anche quando la sorgente inizia ad un indirizzo di memoria minore
  2108. di quello della destinazione: si tratta dell'esempio9l3.s.
  2109.  
  2110. In modo discendente le maschere e lo shift si comportano diversamente
  2111. rispetto al modo ascendente.
  2112. Le maschere funzionano sempre nello stesso modo, ma cambiano le word a cui si
  2113. applicano.
  2114. La maschera contenuta in BLTAFWM viene applicata, come per il caso ascendente,
  2115. alla prima word che blittiamo di ogni riga.
  2116. Siccome pero` in modo discendente blittiamo al contrario, la prima word e` la
  2117. word piu` a destra del rettangolo, mentre in modo ascendente e` la word piu` a
  2118. sinistra.
  2119. Allo stesso modo, la maschera contenuta in BLTALWM viene sempre applicata
  2120. all'ultima word blittata di ogni riga, solo che in modo discendente tale word
  2121. e` la word piu` a sinistra. In sintesi:
  2122.  
  2123. - In modo ascendente (normale) BLTAFWM si applica alla word piu` a sinistra
  2124.   e BLTALWM alla word piu` a destra.
  2125.  
  2126. - In modo discendente BLTAFWM si applica alla word piu` a destra e BLTALWM
  2127.   alla word piu` a sinistra.
  2128.   
  2129. Se guardiamo l'immagine come appare sul video, passando al modo discendente
  2130. le maschere si scambiano le colonne su cui operano. Per verificarlo caricate
  2131. ed eseguite l'esempio lezione9m1.s che fa esattamente le stesse cose
  2132. di lezione9h1.s, solo che opera in modo discendente. Vedrete che le maschere
  2133. producono gli stessi effetti ma scambiando le colonne.
  2134.  
  2135. Lo shift, in modo discendente presenta una differenza fondamentale: viene fatto
  2136. verso SINISTRA, anziche` verso destra. Se specifichiamo un valore di shift pari
  2137. per esempio a 2, la sorgente viene shiftata di 2 pixel VERSO SINISTRA.
  2138. Utilizzando questa caratteristica possiamo realizzare l'effetto di scorrimento
  2139. di un immagine verso sinistra. Lo trovate nell'esempio lezione9m2.s.
  2140.  
  2141. A questo punto, siamo finalmente in grado di realizzare uno degli effetti piu`
  2142. classici delle demo: lo SCROLLTEXT, ovvero un testo che scorre sullo schermo da
  2143. destra verso sinistra.
  2144.  
  2145. Un semplice ma significativo esempio e` la lezione9n1.s, nella quale troverete
  2146. tutte le spiegazioni. Mi raccomando studiate con particolare attenzione questo
  2147. esempio perche` saper fare uno scrolltext e` assolutamente fondamentale per
  2148. un demo-coder!
  2149.  
  2150. Nell'esempio Lezione9n2.s troverete lo scrolltext dell'intro del disco1.
  2151.  
  2152.                                           .-%%%-,
  2153.                                          (       )
  2154.                                        (         )
  2155.                   -~x~-               (          )
  2156.                 /%     %\           (           )
  2157.                |         |         (           )
  2158.                |         |        (           )
  2159.                |     __ _,       (%%%%-(     )
  2160.               /\/\  (. ).)       `_'_', (   )
  2161.                C       __)       (.( .)-(  )
  2162.                |   /%%%  \      (_      ( )
  2163.                /   \ %===='    /_____/` D)
  2164.              /`-_   `---'         \     |
  2165.         .__|%-/~\-%|_/_   |~~~~~~~||    |
  2166.        __.         ||/.\  |       |OooooO
  2167.        \           ---. \ |       |      \ _
  2168.       _-    ,`_'_'  .%\  \|__   __|-____  / )
  2169.      <     -(. ).)   > \  ( .\ (. )     \(_/ )
  2170.       %-       _) \_- ooo @  (_)  @      \(_//.
  2171.      / /_C (-.____)  /((O)/       \     ._/\%_.
  2172.     /   |_\     /   / /\\\\`-----''    _|>o<  |__
  2173.     |     \ooooO   (  \ \\ \\___/     \ `_'_',  /
  2174.      \     \__-|    \  `)\\-~\\ ~--.  /_(.(.)- _\
  2175.       \   \ )  |-`--.`--=\-\ /-//_  '  ( c     D\
  2176.        \_\_)   |-___/   / \ V /.% \/\\\ (@)___/ %|
  2177.       /        |       /   | |.  /`\\_/\/   /   /
  2178.      /         |      (   C`-'` /  |  \/   (/  /
  2179.     /_________-        \  `C__-%   |  /    (/ /
  2180.          | | |          \__________|  \     (/
  2181.  
  2182. Avete capito come funziona lo scrolltext? Se la risposta e` affermativa,
  2183. potete iniziare ad essere soddisfatti di quanto avete imparato. Ormai
  2184. conoscete il funzionamento di base del blitter. Nella prossima lezione
  2185. scopriremo i segreti piu` nascosti di questo potente amico, a partire
  2186. dal piu` grande, il piu` difficile da capire, con il quale abbiamo avuto a che
  2187. fare per tutta questa lezione ma che abbiamo sempre evitato:
  2188. il funzionamento dei MINTERMS!
  2189.  
  2190.